-1

ここで次のコードを見つけました:http://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java

これが機能しない特定のケースがある理由を理解しようとしています。「微妙な」問題の説明を読みました。それを使用volatileすると問題が解決しますが、少し混乱しています。

// 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...
}

基本的に、その時点で「部分的に」構築される可能性があるためhelper == null、ブロック内のチェックが失敗する可能性があるという事実のために、これが失敗すると想定するのは正しいですか?オブジェクトが部分的に構築されている場合、synchronizedJavaはnullを返しませんか?それが問題ですか?

とにかく、ダブルチェックロックを行うのは良い習慣ではないことは知っていますが、理論的には、上記のコードが失敗する理由と、volatile(およびローカル変数の割り当ての追加)がこれを修正する理由に興味がありましたか?これが私がどこかから得たコードです。

// Double-check idiom for lazy initialization of instance fields
private volatile FieldType field;
FieldType getField() {
    FieldType result = field;
    if (result == null) { // First check (no locking)
        synchronized(this) {
            result = field;
            if (result == null) // Second check (with locking)
                field = result = computeFieldValue();
        }
    }
    return result;
}

これについてはすでに1000件の投稿があることは知っていますが、説明では1.5以降のメモリモデルの変更について言及しているようで、それが何に関係しているのかもよくわかりません:-(。

よろしくお願いします!

4

2 に答える 2

4

同期ブロックのヘルパー==nullチェックは、その時点で「部分的に」構築される可能性があるため、失敗する可能性があるため、これが失敗すると想定するのは正しいですか?

はい、その通りです。これは、順不同の書き込みで説明されています。helper = new Helper()メモリ割り当て、コンストラクターの呼び出し、および割り当ての3つのステップで構成されます。JITコンパイラは、メモリ割り当て後(新しいオブジェクトへの参照を返す)、コンストラクター呼び出しの前に、命令を自由に並べ替えて割り当てを行うことができます。volatileを使用すると、並べ替えが防止されます。

于 2012-09-16T17:34:57.993 に答える
1

フィールドへの書き込みがメインメモリvolatileに「フラッシュ」されるため、フィールドを宣言する必要があります。それ以外の場合、JVM仕様では、各スレッドがフィールドのローカルバージョンを保持し、その書き込みを他のスレッドに伝達することはできません。これは、JVMで積極的な最適化を可能にするため、一般的には便利です。

お役に立てば幸いです。それ以外の場合は、非常に濃いコーヒーと非常に静かな部屋を用意してから、Javaメモリモデルを読んで、その仕組みとスレッド間の相互作用について説明することをお勧めします。スレッドが(共有)メモリへの書き込みを他のスレッドに通信するために必要な状況が少なく、JVMが実行できる読み取りと書き込みの並べ替えに驚かれると思います。

エキサイティングな読み物!

于 2012-09-16T17:27:28.950 に答える