JVM指令重排导致Singleton双重锁定出错
来源:互联网 发布:rgb颜色渐变算法 c 编辑:程序博客网 时间:2024/05/20 06:24
指令重排导致单例模式失效
我们都知道一个经典的懒加载方式的单例模式:
public class Singleton {
private static Singleton instance = null;
private Singleton() { }
public static Singleton getInstance() {
if(instance == null) {
synchronzied(Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
看似简单的一段赋值语句:instance = new Singleton();,其实JVM内部已经转换为多条指令:
memory = allocate(); //1:分配对象的内存空间
ctorInstance(memory); //2:初始化对象
instance = memory; //3:设置instance指向刚分配的内存地址
但是经过重排序后如下:
memory = allocate(); //1:分配对象的内存空间
instance = memory; //3:设置instance指向刚分配的内存地址,此时对象还没被初始化
ctorInstance(memory); //2:初始化对象
可以看到指令重排之后,instance指向分配好的内存放在了前面,而这段内存的初始化被排在了后面,在线程A初始化完成这段内存之前,线程B虽然进不去同步代码块,但是在同步代码块之前的判断就会发现instance不为空,此时线程B获得instance对象进行使用就可能发生错误。
修改:
public class Singleton {private static volatile Singleton instance = null;private Singleton() { }public static Singleton getInstance() {if(instance == null) {synchronzied(Singleton.class) {if(instance == null) {instance = new Singleton();}}}return instance;}}
- JVM指令重排导致Singleton双重锁定出错
- JVM 指令重排
- JVM之指令重排分析
- JVM 编译之指令重排
- JVM之指令重排分析
- JVM之指令重排分析
- 单例(Singleton) 双重锁定(Double-Check Locking)
- 双重锁定
- 深入理解JVM 系列JVM运行机制 JVM内存模(volatile,指令重排)
- 深入理解JVM 系列JVM运行机制 JVM内存模(volatile,指令重排)
- 双重检查锁定
- 双重检查锁定模式
- 双重检查锁定模式
- 双重检查锁定
- Java双重检查锁定
- 双重检查锁定
- 双重检验锁定单例模式的优化写法(非volatile,全版本jvm通用)
- JMM 指令重排
- oracle中常用sql语句
- #OSG+VS#07第四周
- spring cloud 学习地址
- Android 7.0 init.rc的一点改变
- 【干货】前端rem单位的正确使用姿势
- JVM指令重排导致Singleton双重锁定出错
- 1068. 万绿丛中一点红(20)
- CMake的简单例子
- 王道计算机网络--3.6局域网
- C++鸡兔同笼问题(做对了有奖品哦!)(五天后发解答)
- mocha设置延时启动/等待(setTimeout)
- 微信支付开发V3版
- poj3616
- C++ 图像边界扩充函数copyMakeBorder