这是 Java double checked locking 的后续内容.
以下代码片段有 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
(希望)是 volatile 的,这将确保所有初始化对后来的读者都是可见的。
顺便说一句,您实际上没有必要学习允许重新排序的所有规则:这只是 JIT 编译器实现者的必读内容。
作为 Java 程序员,您需要记住的是 Java 内存模型为您提供的两个简单保证(一个是关于 synchronized
,另一个是关于 volatile
)。 JMM 重写(从 JLS 3 开始)的全部目的是让我们能够针对非常简单的并发模型进行编程。
关于Java双重检查锁定解决方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18023158/