为什么双重检查单例模式变量要声明为volatile类型

双重检查能够减小锁机制带来的开销,使用volatile来禁止指令重排序,因为new 对象并不是一个原子操作,new 对象时会有三个步骤

  1. 申请内存
  2. 调用构造器初始化对象
  3. 将对象的引用赋值给变量

其中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;
    }
    //怎样测试他有指令重排序呢
}

 

posted on 2021-01-29 11:31  lyfa  阅读(110)  评论(0)    收藏  举报

导航