单例模式:
简单来说就是一个类只能构建一个对象的一种设计模式
1、饿汉模式
class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {}//私有的构造函数
public static Singleton getInstance() {
return instance;
}
}
2、懒汉模式
class Singleton {
private static Singleton instance = null;
private Singleton() {}//私有的构造方法
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
对于上面的两个代码,看到的差别就是饿汉模式自己主动创建一个对象,而懒汉模式刚开始为null,需要进行判断才知道要不要创建对象;由于单例模式是一个类只能创建一个对象,因此构造方法是私有的,只能在类内进行对象的创建。
这两个写法仅仅是单线程下才可以进行成功的创建,如果是多线程下,会存在线程安全的问题
3、多线程的懒汉模式(双重校验锁)
class Singleton {
private static volatile Singleton instance = null;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
//new对象分解三条指令:1、分配内存空间2、初始化对象3、赋值给变量
}
}
}
return instance;
}
}
第一个判空是为了提高小效率,第二个判空是为了防止再创建一个对象实例,当两个线程同时访问的时候,线程A和线程B都经过了第一次的判空操作,线程A进入synchronized代码块,创建一个对象,退出synchronized代码块,释放锁之后,线程B也进入代码块,如果没有第二次判空操作,线程B还是会创建一个新的对象
volatile关键字是为了保证可见性和防止指令重排序