为什么用Java检查双重检查锁定? [英] Why is double-checked locking broken in Java?

查看:803
本文介绍了为什么用Java检查双重检查锁定?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据说字段赋值总是原子的,除了long或double字段。

It's stated that fields assignment is always atomic except for fields of long or double.

但是,当我读到为什么双重检查锁定被破坏的解释时,据说问题在于赋值操作:

But, when I read an explaination of why double-check locking is broken, it's said that the problem is in assignment operation:

// Broken multithreaded version
// "Double-Checked Locking" idiom
class Foo {
    private Helper helper = null;
    public Helper getHelper() {
        if (helper == null) {
            synchronized(this) {
                if (helper == null) {
                    helper = new Helper();
                }
            }
        }
        return helper;
    }

    // other functions and members...
}





  1. 线程A注意到该值未初始化,因此它获得
    锁并开始初始化
    值。

  2. 由于某些编程语言的语义,编译器生成的代码
    允许
    更新共享变量以将
    指向部分在A完成
    初始化之前构造对象

  3. 线程B注意到共享变量已经初始化(或者出现
    ),并返回其值。
    因为线程B认为值已经初始化了
    ,所以它不会获得
    获取锁定。如果B在所有初始化完成之前使用对象
    由B看到A的
    (因为A
    尚未完成初始化或
    ,因为一些初始化值$对象中的b $ b还没有渗透到内存B使用的
    (缓存
    连贯性)),程序可能会
    崩溃。

    (来自 http://en.wikipedia.org/wiki/Double- checked_locking )。

  1. Thread A notices that the value is not initialized, so it obtains the lock and begins to initialize the value.
  2. Due to the semantics of some programming languages, the code generated by the compiler is allowed to update the shared variable to point to a partially constructed object before A has finished performing the initialization.
  3. Thread B notices that the shared variable has been initialized (or so it appears), and returns its value. Because thread B believes the value is already initialized, it does not acquire the lock. If B uses the object before all of the initialization done by A is seen by B (either because A has not finished initializing it or because some of the initialized values in the object have not yet percolated to the memory B uses (cache coherence)), the program will likely crash.
    (from http://en.wikipedia.org/wiki/Double-checked_locking).


什么时候可能?是否有可能在64位JVM分配操作上不是原子的?
如果不是那么双重检查锁定是否真的被打破了?

When is it possible? Is it possible that on 64-bit JVM assignment operation isn't atomic? If no then whether "double-checked locking" is really broken?

推荐答案

问题不是原子性,它是排序。只要之前发生的事情未被违反。因此,在执行来自类 Helper 的构造函数的所有指令之前,运行时理论上可以调度更新 helper 的指令。

The problem is not atomicity, it's ordering. The JVM is allowed to reorder instructions in order to improve performance, as long as happens-before is not violated. Therefore, the runtime could theoretically schedule the instruction that updates helper before all instructions from the constructor of class Helper have executed.

这篇关于为什么用Java检查双重检查锁定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆