双重检查锁定的缺点与改进
双重检查锁定的延时初始化: 1 class DoubleCheckLocking{ 2 private DoubleCheckLocking() {} 3 private static DoubleCheckLocking instance; 4 public static DoubleCheckLocking getInstance(){ 5 if (instance == null){ 6 synchronized (DoubleCheckLocking.class){ 7 if (instance == null) 8 instance = new DoubleCheckLocking(); 9 } 10 } 11 return instance; 12 } 13 } 双重检查锁定看起来似乎很完美,但这是一个错误的优化!执行程序读取到第5行instance不为空时,instance引用的对象可能还没有完成初始化。 程序第8行所做的操作如下: 1:分配对象的内存空间 2:初始化对象 3:设置instance指向刚分配的内存地址 步骤2和3之间可能发生重排序,导致上面的问题。 解决方法: 1:不让2和3重排序 2:允许2和3重排序,但不允许其他线程“看到”这个重排序。 解决方案1:基于volatile的解决方案 1 class