[英]Java double-checked locking solution?
这是Java双重检查锁定的后续内容。
以下代码段具有2个有趣的特征。
1)在准备好使用对象之前,需要调用单独的init()方法。 所以volatile并没有帮助(我知道,为什么我不只是将init()中的代码放入构造函数中呢?在这里出于说明目的)。
2)它使用tmp变量进行初始化,并在初始化完成后分配给实例。
if (instance == null) {
synchronized (mutex) {
if (instance == null) {
AClass tmpInstance = new AClass();
tmpInstance.init();
instance = tmpInstance;
}
}
}
那么,这是否受到重新排序问题的影响,即是否可以在调用tmpInstance.init()之前将实例分配给tmpInstance?
谢谢,里奇
重要的是,在完成所有初始化之后,您将分配给instance
作为最后一个操作。 由于instance
(希望)是易失的,因此将确保以后的读者可以看到所有初始化。
顺便说一句,实际上您不需要学习所有允许的重新排序规则:这是仅JIT编译器实施者的必读内容。
作为Java程序员,您需要记住的是Java内存模型为您提供的两个简单保证(一个关于synchronized
,另一个关于volatile
)。 JMM重写的全部要点(从JLS 3开始)是为了使我们能够针对非常简单的并发模型进行编程。
那么,这是否受到重新排序问题的影响,即是否可以在调用tmpInstance.init()之前将实例分配给tmpInstance?
否,但是它受到volatile确实解决的可见性问题的困扰。 因此,您仍应声明instance
volatile。
现在之所以不对其进行重新排序。 监视器进入后,无法对普通商店进行重新排序。
http://g.oswego.edu/dl/jmm/cookbook.html
第一次操作:MonitorEnter
第二次操作:NormalStore
可以重新排序:否
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.