繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM