7

マルチスレッド アプリケーションとシングルトン クラスがあります。

public final class Singleton {

    private static MyClass mc;

    public static final Object getInstance() {
            if(mc == null) {
                mc = new MyClass();
            }
            return mc;
    }

}

もちろん、これは一般的なマルチスレッド シナリオでは機能しません。ただし、次のシナリオを検討してください。

  • 最初はスレッドが1つしかありません
  • この 1 つのスレッドがgetInstance()初めて呼び出し、mc が初期化されます。
  • その後、他のすべてのスレッドは最初のスレッドによって開始されます。

私の仮定:

フィールドの初期化とオブジェクトの構築は、他のスレッドを開始するmc後続のすべての呼び出しの前に発生するため、これは機能するはずです。Thread.start()そして、Thread.start()スレッドの for は、そのスレッドの他のすべてのアクションの前に発生します。したがって、すべてのスレッドで正しい値が返されるmcように、他のすべてのスレッドですべてのアクションが先行発生します。getInstance()

この仮定は正しいですか?なぜ/なぜしないのですか?

4

1 に答える 1

5

あなたの分析は確かに完璧です。

正確に言えば、1 つのスレッドで順次発生するすべての事象には、事前発生の関係があります (明らかに、このように言います:「x と y が同じスレッドのアクションであり、x がプログラム順で y の前にある場合、hb(x, y)" )

JLSの17.4.5は、次のように続けています。

「スレッドでの start() の呼び出しは、開始されたスレッドのアクションの前に発生します。」

まとめると、シングルトンのインスタンス化と開始されたスレッドの間で順序の前に明確なことが発生するため、最新の値が表示されることが保証されます。

簡単に言うと、作成されたスレッドは、作成される前にその親が行ったすべてのことを確認することが保証されています。そうしないと、並行プログラミングはほぼ不可能になります。

于 2014-11-06T22:53:17.657 に答える