1

私が提起した以前の質問に関して、

    public static Singleton getInstanceDC() {
    if (_instance == null) {                // Single Checked (1)
        synchronized (Singleton.class) {
            if (_instance == null) {        // Double checked (2)
                _instance = new Singleton();
            }
        }
    }
    return _instance;

}

2 番目のインスタンスの null チェック条件を使用する必要があるのはなぜですか。それはどのような影響を与える可能性がありますか?

4

1 に答える 1

4

スレッドが操作をインターリーブする方法を確認できるように、行に番号を付けてみましょう。

if (_instance == null) {                // L1
    synchronized (Singleton.class) {    // L2
        if (_instance == null) {        // L3
            _instance = new Singleton();// L4
        }
    }
}

L3 のチェックなしのインターリーブを考えてみましょう。

  1. _instanceスレッド 1はL1 に到達し、null
  2. スレッド 2 は L1 に到達し_instancenull
  3. スレッド 1 は L2 でミューテックスを取得します
  4. スレッド 2 は L2 でミューテックスを取得しようとしますが、ブロックされます
  5. スレッド 1 は新しいインスタンスを作成し、L4 で割り当てます
  6. スレッド 1 が L2 からミューテックスを解放する
  7. スレッド 2 は L2 でミューテックスを取得します
  8. スレッド 2 は新しいインスタンスを作成し、L4 で割り当てます
  9. スレッド 2 は L2 からミューテックスを解放します

の 2 つのインスタンスが作成されましたSingleton。各スレッドは独自のインスタンスを返します。

_instanceL3 でのチェックでは、ステップ 7 でスレッド 2 のビューがスレッド 1 のビューと同期されたため、ステップ 8 は発生しません。したがって、 のインスタンスは 1 つだけSingleton作成されます。

于 2015-10-30T03:27:24.773 に答える