学过单例模式我们都知道,双重校验是单例模式线程安全的懒汉式实现模式。代码如下:
/**
* @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个步骤:
- 分配内存空间
- 初始化对象
- 将对象指向刚分配的内存空间
但是为了性能原因,编译器可能会把第二步跟第三步进行重排序:
- 分配内存空间
- 将对象指向刚分配的内存空间
- 初始化对象
加入有A、B两个线程来获取该单例对象,当A线程执行到重排序的第二步时,此时对象不为null。B线程便能获取到对象,但是该对象并没有完成初始化。
所以此处使用volatile关键字的作用就是为了防止指令重排序。
© 版权声明
THE END
暂无评论内容