Java双重检查锁定解决方案?

Java双重检查锁定解决方案?,java,synchronization,singleton,double-checked-locking,Java,Synchronization,Singleton,Double Checked Locking,这是我们的后续报道 下面的代码片段有两个有趣的特征 1) 它需要在对象准备好使用之前调用单独的init()方法。所以volatile没有帮助(我知道,为什么我不把init()中的代码放到构造函数中呢?这里是为了说明的目的) 2) 它使用tmp变量进行初始化,并在初始化完成后分配给实例 if (instance == null) { synchronized (mutex) { if (instance == null) { AClass tmpInstance = new

这是我们的后续报道

下面的代码片段有两个有趣的特征

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

谢谢, 丰富的

那么,这个问题是否受到重新排序问题的影响,也就是说,实例可能是 是否在调用tmpInstance.init()之前分配给tmpInstance

不,但它受到volatile解决的可见性问题的影响。因此,您仍然应该声明
实例
volatile

现在是它不需要重新排序的原因。监视器输入后,无法对正常存储重新排序

第一次操作:监视器中心

第二个操作:NormalStore

可以重新订购:没有


重要的是,在所有初始化完成后,您要将
实例
指定为最后一个操作。由于
instance
是(希望是)易变的,这将确保所有初始化对以后的读者可见

顺便说一句,您真的没有必要学习所有允许的重新排序规则:这只是JIT编译器实现者的必读内容

作为Java程序员,您只需要记住Java内存模型为您提供的两个简单保证(一个是关于
同步的
,另一个是关于
易失性的
)。JMM重写的全部要点(从JLS3开始)是允许我们针对一个非常简单的并发模型进行编程