double check 单例模式:
- 第一次检查,当 instance 为 null 的时候,进入对象实例化逻辑,否则直接返回。
- 加同步锁,这里是类锁。
- 第二次检查才是关键。如果不加这次判空动作,可能会有多个线程进入同步代码块,进而生成多个实例。
- 最后一个关键点是 volatile 关键字。在一些低版本的 Java 里,由于指令重排的缘故,可能会导致单例被 new 出来后,还没来得及执行构造函数,就被其他线程使用。 这个关键字,可以阻止字节码指令的重排序,在写 double check 代码时,习惯性会加上 volatile。
public class DoubleCheckSingleton {
private volatile static DoubleCheckSingleton instance = null;
private DoubleCheckSingleton() {
}
public static DoubleCheckSingleton getInstance() {
if (null == instance) {
synchronized (DoubleCheckSingleton.class) {
if (null == instance) {
instance = new DoubleCheckSingleton();
}
}
}
return instance;
}
}
double check 的写法繁杂,注意点很多,它现在其实是一种反模式,已经不推荐使用了
public class EnumSingleton {
private EnumSingleton() {
}
public static EnumSingleton getInstance() {
return Holder.HOLDER.instance;
}
private enum Holder {
HOLDER;
private final EnumSingleton instance;
Holder() {
instance = new EnumSingleton();
}
}
public static void main(String[] args) {
System.out.println(getInstance());
}
}