- 一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
- 1、单例类只能有一个实例。
- 2、单例类必须自己创建自己的唯一实例。
- 3、单例类必须给所有其他对象提供这一实例。
1、懒汉式,线程不安全.
public class SingletonPattern {
private static SingletonPattern instance;
//必须构造私有
private SingletonPattern(){}
public static SingletonPattern getInstance(){
if(instance ==null ){
instance= new SingletonPattern();
}
return instance;
}
}
2、懒汉式,线程安全.加synchronized 锁,但加锁会影响效率.
public class SingletonPattern {
private static SingletonPattern instance;
//必须构造私有
private SingletonPattern(){}
//加锁
public static synchronized SingletonPattern getInstance(){
if(instance == null ){
instance = new SingletonPattern();
}
return instance;
}
}
3、饿汉式,线程安全.这种方式比较常用,但容易产生垃圾对象。
public class SingletonPattern {
private static SingletonPattern instance = new SingletonPattern();
//必须构造私有
private SingletonPattern() {
}
public static SingletonPattern getInstance() {
return instance;
}
}
为什么说单例模式的饿汉式是线程安全的?
类加载的方式是按需加载,且只加载一次,加载类的时候,由于static 修饰instance ,该变量是类变量,只会被加载一次,线程每次都只能也必定只可以拿到这个唯一的对象。即饿汉式单例天生就是线程安全的.
4、双重校验锁
public class SingletonPattern {
private volatile static SingletonPattern instance;
//必须构造私有
private SingletonPattern() {
}
public static SingletonPattern getInstance() {
if (instance == null) {
synchronized (SingletonPattern.class) {
if(instance ==null ){
instance = new SingletonPattern();
}
}
}
return instance;
}
}
5、instance为什么一定要是static的?
1.通过静态的类方法(getInstance) 获取instance,该方法是静态方法,instance由该方法返回(被该方法使用),如果instance非静态,无法被getInstance调用;
2.instance需要在调用getInstance时候被初始化,只有static的成员才能在没有创建对象时进行初始化。且类的静态成员在类第一次被使用时初始化后就不会再被初始化,保证了单例;
3.static类型的instance存在静态存储区,每次调用时,都指向的同一个对象。其实存放在静态区中的是引用,而不是对象。而对象是存放在堆中的。