首选第一种,如果需要延迟加载,就用第二种。第三种复杂,容易漏写东西。
三种都是线程安全的,即时单线程也推荐这么写。
第一种:饿汉式,类加载时创建
public Class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return INSTANCE;
}
}
缺点:INSTANCE是在类加载时进行创建,如果依赖其他类初始化,这样就不行
第二种: 懒汉式,静态内部类
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
第三种:懒汉式,双重校验锁
public Class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized(Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
为什么要有volatile关键字,如果没有,线程执行 instance = new Singleton()时,如果指令重排,线程B可能会拿到一个不为null,但是没有初始化的instance。
参考大佬们的文章:
https://www.jianshu.com/p/eb30a388c5fc