在一些书上和博客上看到说 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 的加锁和解锁之间能够有确定的顺序,但是多个线程下 synchronized 之前的非空判断之间并不能保证顺序。所以需要用 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 关键字还需要禁止指令重排序干嘛
|