为什么双重检查单例模式变量要声明为volatile类型
双重检查能够减小锁机制带来的开销,使用volatile来禁止指令重排序,因为new 对象并不是一个原子操作,new 对象时会有三个步骤
- 申请内存
- 调用构造器初始化对象
- 将对象的引用赋值给变量
其中1永远是第一步因为2,3都依赖于1,而2,3可能发生指令重排
在多线程情况下如果线程1执行 new Instance() 操作时先进行的步骤3,而没有对对象进行初始化,此时线程2进行判断时instance不为空,这就造成了错误。
public class InstanceFactory { private Instance instance = null; public Instance getInstance(){ if(instance == null){ synchronized (instance){ if(instance == null){ instance = new Instance("hj"); } } } return instance; } //怎样测试他有指令重排序呢 }