【问题标题】:Java double-checked locking solution?Java双重检查锁定解决方案?
【发布时间】:2013-08-02 17:52:18
【问题描述】:

这是Java double checked locking 的后续报道。

以下代码 sn-p 有 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?

谢谢, 丰富

【问题讨论】:

    标签: java synchronization singleton double-checked-locking


    【解决方案1】:

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

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

    作为 Java 程序员,您需要牢记的是 Java 内存模型为您提供的两个简单保证(一个是关于 synchronized,另一个是关于 volatile)。 JMM 重写(从 JLS 3 开始)的全部意义在于允许我们针对非常简单的并发模型进行编程。

    【讨论】:

      【解决方案2】:

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

      不,但它会受到 volatile 确实解决的可见性问题的影响。所以你仍然应该声明instance volatile。

      现在是它不受重新排序的原因。监视器进入后无法重新订购普通商店。

      http://g.oswego.edu/dl/jmm/cookbook.html

      第一个操作:MonitorEnter

      第二次操作:NormalStore

      可以重新订购:否

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-04
        • 1970-01-01
        • 2022-11-01
        相关资源
        最近更新 更多