フィールドの割り当ては、longまたはdoubleのフィールドを除いて常にアトムであると言われています。Javaでダブルチェックのロックが解除されるのはなぜですか?
しかし、私はダブルチェックロックが壊れている理由の、について説明を読んだとき、問題が代入演算であると言われています:値が初期化されていない
// 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...
}
- スレッドAの通知したがって、 ロックを取得し、 値の初期化を開始します。
- 何らかのプログラミング言語の意味論に、コンパイラによって生成されたコードは Aが初期化を実行完了する前に、部分的に構築されたオブジェクトに を指すように、共有変数を更新することができます。
- スレッドBは、共有変数が初期化されていることに気付き(または と表示されます)、その値を返します。 スレッドBは、既に値が であると考えているので、 はロックを取得しません。 BがAによって を行って、初期化のすべての前にオブジェクト を使用している場合は初期化された値のいくつかは、オブジェクト内の がまだメモリBに を浸透していないため がそれを初期化したり が完了していないので、どちらか(Bで見られています使用(キャッシュ 一貫性))、プログラムはおそらく クラッシュします。
(http://en.wikipedia.org/wiki/Double-checked_lockingから)。
いつ可能ですか? 64ビットJVMの割り当て操作がアトミックでない可能性はありますか? 「ダブルチェックロック」が本当に壊れていないかどうかを確認します。
64ビットJVMでは違いはありません。 – rapadura
可能な複製http://stackoverflow.com/questions/12448864/java-double-locking-can-someone-explain-more-simply-why-intuition-wouldnt-wor/12449110?noredirect=1#comment26446551_12449110 –