双重检查锁定

less than 1 minute read

Published:

“聪明”的单例模式

public class Singleton {
  private static Singleton instance;
  private Singleton() {}
  public static Singleton getInstance() {
    if(instance == null) {
      synchronized(Singleton.class) {
        if(instance == null) {
          instance = new Singleton();
        }
      }
    }
    return instance;
  }
}

问题根源

memory = allocate(); //1:分配对象的内存空间
ctorInstance(memory); //2:初始化对象
instance = memory; //3:设置instance指向刚分配的内存地址

代码2和代码3可能发生重排序,导致访问到一个还没初始化的对象

基于volatile的解决方案(JDK5或更高版本,volatile语义被加强)

public class Singleton {
  private volatile static Singleton instance;
  private Singleton() {}
  public static Singleton getInstance() {
    if(instance == null) {
      synchronized(Singleton.class) {
        if(instance == null) {
          instance = new Singleton();
        }
      }
    }
    return instance;
  }
}

## 基于类初始化的解决方案(类初始化锁)

public class Singleton {
  private Singleton(){}
  private static class InstanceHolder {
    public static Singleton instance = new Singleton();
  }
  public static Singleton getInstance() {
    return InstanceHolder.instance;
  }
}