# 双重检查锁定

## “聪明”的单例模式

```java
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;
  }
}
```

## 问题根源

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

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

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

```java
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;
  }
}
```

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

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