ウィキペディアで DCL について読んでいて、DCL の問題と提案された解決策について疑問に思っていました。つまり、なぜvolatile
キーワードが必要なのですか? つまり、DCL を使用すると、部分的に構築されたオブジェクトがスレッドによって使用される場合があります。提案された解決策 (JAVA 5+ の場合):
// Works with acquire/release semantics for volatile
// Broken under Java 1.4 and earlier semantics for volatile
class Foo {
private volatile Helper helper;
public Helper getHelper() {
Helper result = helper;
if (result == null) {
synchronized(this) {
result = helper;
if (result == null) {
helper = result = new Helper();
}
}
}
return result;
}
// other functions and members...
}
volatile
さて、私の質問は、 from ヘルパーをドロップしないのはなぜですか? 私が間違っている場合は訂正してくださいhelper = result = new Helper();
。
result = new Helper();
helper = result;
このシナリオではhelper
、オブジェクトが完成するまで参照を取得できません。そうじゃない?どのようにvolatile
うまくいっていますか?
編集:このコードを想定:
class Foo {
private volatile Helper helper;
public Helper getHelper() {
Helper result = helper;
if (result == null) {
synchronized(this) {
result = helper;
if (result == null) {
result = new Helper();
result.someMethod();
helper = result;
}
}
}
return result;
}
}
初期化後の次の行で完全に初期化されたオブジェクトが保証されない場合、そのオブジェクトに対してメソッドを呼び出すことはできません。できますか?