volatile+DCL(双重检测)单例

作者:陆金龙    发表时间:2022-12-30 22:28   

关键词:DCL  volatile  

DCL(Double Check Lock)双重检测锁。减少了锁粒度,如果第一次检查instance不为null,那么就不需要执行下面的加锁和初始化操作。

利用volatile的禁止指令重排特性,弥补并发情形下双重检测单例模式的缺陷。

public class Singleton {
    // 使用volatile的禁止指令重排特性,避免获取到的实例因指令重排原因未完成初始化,使用时报错。
    private volatile static Singleton instance;
    private Singleton(){
    }

    public static Singleton getInstance() {
        if(instance == null){
            // 同步只单例类实例创建的时候才被需要,所以synchronized用在创建实例的代码块,而不是整个方法上。
            synchronized (Singleton.class){
                // 有可能当前线程获取到锁的时候,刚好是上一个线程完成了实例的创建后释放了锁。因此再做一次是否为null的判断。
                if(instance == null){
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}