关于多线程下的双重检测模式
来源:9-5 jmm的内存可见性
幕布斯9391928
2019-12-26
在单例的双重检测模式下,都为代码块增加synchronized修饰了,此时已经是一个单线程下的操作了,即使发生了指令重排,但是结果不是依然是对的吗?
写回答
2回答
-
new操作会经历三个过程
分配内存
执行Singleton构造函数
将实例指向分配的内存
由于是synchronized修饰的,所以不保证操作的顺序,只保证原子性
如果按照1->3->2去执行的话,当线程A执行完3的时候,instance是有值了,但是还没执行Singleton构造函数初始化实例,然后线程B在synchronized外面的if判断时,由于instance非空,所以直接返回,获取到一个没有实例化完成的对象,可以细细体会一下
232020-04-03 -
翔仔
2020-04-03
同学好,对着代码说好点。。
public class Singleton { private static Singleton instance; private Singleton(){} public static Singleton getInstance(){ //第一次检测 if (instance==null){ //同步 synchronized (Singleton.class){ if (instance == null){ //多线程环境下可能会出现问题的地方 instance = new Singleton(); } } } return instance; } }
1)instance并没有被锁呀,虽然A在执行1 3 2 的时候锁没被释放,但是instance已经在执行3即分配内存空间但是没有创建完成的时候就有值了。。B此时去用的时候,在第一个if里就能获取到instance有值的反馈,就不会去执行sync里面的逻辑了,而是直接将不完整的实例给返回。
2)还是第一个问题,你要明确锁的是啥,锁的只是Singleton这个Class对象,没锁它的实例呀。。
00
相似问题