采纳答案成功!
向帮助你的同学说点啥吧!感谢那些助人为乐的人
在单例的双重检测模式下,都为代码块增加synchronized修饰了,此时已经是一个单线程下的操作了,即使发生了指令重排,但是结果不是依然是对的吗?
new操作会经历三个过程
分配内存
执行Singleton构造函数
将实例指向分配的内存
由于是synchronized修饰的,所以不保证操作的顺序,只保证原子性
如果按照1->3->2去执行的话,当线程A执行完3的时候,instance是有值了,但是还没执行Singleton构造函数初始化实例,然后线程B在synchronized外面的if判断时,由于instance非空,所以直接返回,获取到一个没有实例化完成的对象,可以细细体会一下
非常感谢!
老师,我还有些地方没想明白。 1)这里的意思是按照1->3->2去执行的话,当线程A执行完3的时候,CPU给B占用了么?那这时线程A还没执行完,类锁还没有释放的,instance也是一个类变量,为什么可以说线程B在synchronized外面的if判断的? 3)如果这里线程B还能读取instance,说明synchronized是类似我们数据库中讲的共享锁么?就是事务还没执行完成就可以读取中间数据,所以读到了instance为null直接返回导致的出错呢?
同学好,已经回复了哈
同学好,对着代码说好点。。
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对象,没锁它的实例呀。。
登录后可查看更多问答,登录/注册
招聘季即将到来,让百度资深面试官来为你的高薪Offer保驾护航
1.8k 27
2.7k 22
1.2k 15
1.4k 14
1.3k 14