
在一些书上和博客上看到说 synchronized 有禁止指令重排序的作用,如果这样的话单例模式的双重检查锁模式就不需要 volatile 修饰了吧?求助大佬...
1 sagaxu 2017-10-14 20:19:33 +08:00 via Android 理解有误 |
2 juxingzhutou 2017-10-14 20:23:00 +08:00 synchronized 都已经加锁了你还要双重锁检查干嘛? |
4 tuzhenyu OP @juxingzhutou 单例模式的双重检查是双重非空检查,只加了一个 synchronized 锁 public class DoubleCheckedLocking { private static Instance instance; public static Instance getInstance() { if (instance == null) { synchronized (DoubleCheckedLocking.class) { if (instance == null) instance = new Instance(); } } return instance; } } |
5 iEverX 2017-10-14 20:31:50 +08:00 没有,需要加 volatile 的 |
6 juxingzhutou 2017-10-14 20:36:26 +08:00 @tuzhenyu 你这样写的话 synchronized 并不能保证在它之前的非空判断的“顺序”问题,根据 JSR-133 定义的 JMM,synchronized 的加锁和解锁之间能够有确定的顺序,但是多个线程下 synchonized 之前的非空判断之间并不能保证顺序。所以需要用 volatile 来保证非空判断之间的 happens-before 关系。 有兴趣的话建议你完整地看一下 JSR-133 相关的文章。 |
7 tuzhenyu OP @juxingzhutou 好的 谢谢! |
9 NUT 2017-10-15 15:36:02 +08:00 @juxingzhutou 正解。 @tuzhenyu JMM 会保证程序在允许范围内执行指令混排,所以在视觉上会给人造成顺序执行的假象。除了用 syn 意外还能使用 乐观锁的 思想来处理。看着这个 访问 http://www.hollischuang.com/archives/1866 |
10 XiLemon 2017-10-15 16:35:20 +08:00 via iPhone 楼主搜一搜陈皓和 wuchong 的单例模式正确写法的 blog |
11 hantsy 2017-10-16 10:00:09 +08:00 来看看 Bob Lee ( Guice 作者) 的双检模型: http://blog.crazybob.org/2007/01/lazy-loading-singletons.html |
12 ppaapc 2017-10-16 13:05:38 +08:00 加了 synchronized 关键字还需要禁止指令重排序干嘛 |