单例模式-双重检验锁定

设计模式🙈🙊🙉

Posted by 华仔 on February 19, 2019

在单例模式的实现上有一种双重检验锁定的方式(Double-checked Locking)

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

为什么要加volatile?

因为:instance = new Singleton()中

  1. 分配对象的内存空间;

  2. 初始化对象;

  3. 设置instance指向刚分配的内存地址。但由于存在重排序的问题,可能有以下的执行顺序:

因为重排序可能产生的执行顺序

如果2和3进行了重排序的话,线程B进行判断if(instance==null)时就会为false,而实际上这个instance并没有初始化成功,显而易见对线程B来说之后的操作就会是错得。而用volatile修饰的话就可以禁止2和3操作重排序,从而避免这种情况。volatile包含禁止指令重排序的语义,其具有有序性

三大性质总结:原子性,有序性,可见性