单例模式双重校验与volatile关键字

学过单例模式我们都知道,双重校验是单例模式线程安全的懒汉式实现模式。代码如下:

/**
 * @Author shenxy
 * @Date 2022/8/26 19:29
 * @Version 1.0
 */
public class Singleton {
    private volatile static Singleton singleton;

    private Singleton() {
    }

    public static Singleton getSingleton() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }

        return singleton;
    }
}

不知道大家有没有想过,volatile关键字在这里是何作用。

其实 singleton = new Singleton() 这行代码分为3个步骤:

  1. 分配内存空间
  2. 初始化对象
  3. 将对象指向刚分配的内存空间

但是为了性能原因,编译器可能会把第二步跟第三步进行重排序:

  1. 分配内存空间
  2. 将对象指向刚分配的内存空间
  3. 初始化对象

加入有A、B两个线程来获取该单例对象,当A线程执行到重排序的第二步时,此时对象不为null。B线程便能获取到对象,但是该对象并没有完成初始化。

所以此处使用volatile关键字的作用就是为了防止指令重排序。

© 版权声明
THE END
请撒泡尿证明你到此一游
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容