0

ウィキペディアでシングルトン パターンのこのコードに出くわしました。nullを2回チェックする目的/ロジックを誰かが説明できますか?

public class SingletonDemo {
    private static volatile SingletonDemo instance = null;

    private SingletonDemo() {       }

    public static SingletonDemo getInstance() {
            if (instance == null) {
                    synchronized (SingletonDemo .class){
                            if (instance == null) {
                                    instance = new SingletonDemo ();
                            }
                  }
            }
            return instance;
    }
  }
4

5 に答える 5

2

ウィキペディアのリンクからの引用:

この方法では、ダブルチェック ロックを使用します。

http://en.wikipedia.org/wiki/Double_checked_locking_pattern#Usage_in_Java

于 2013-04-14T03:58:11.487 に答える
1

「二重チェックのロック」よりも、遅延初期化に内部クラスを使用することをお勧めします。

public class Singleton {
  // Private constructor prevents instantiation from other classes
  private Singleton() {}

  /**
   * SingletonHolder is loaded on the first execution of Singleton.getInstance() 
   * or the first access to SingletonHolder.INSTANCE, not before.
   */
  private static class SingletonHolder { 
    private static final Singleton INSTANCE = new Singleton();
  }

  public static Singleton getInstance() {
    return SingletonHolder.INSTANCE;
  }
}

二重チェックのロックは絶対確実ではありません。静的内部クラスは、スレッドセーフなシングルトン クラスを遅延して作成するために JVM によって保証されます。

于 2013-04-14T04:06:54.530 に答える
0

同じメソッドを呼び出す 2 つのスレッド T1 と T2 があるとします。

ここで、T1 は最初のチェックを通過し、インスタンスが null であることを発見し、その後スリープ状態になりました。T2 が作動し (常に発生するわけではありませんが、発生する場合もあります)、最初のチェックを通過し、オブジェクトが null であることを検出し、ロックを取得してオブジェクトを作成するとします。

ここで T1 が起動し、ロックを取得します。この時点で再度 null をチェックしないと、T1 は T2 によって作成されたオブジェクトが既に存在することを認識できません。したがって、ダブルチェック。

最初に同期と null チェックを行わないのはなぜですか? null をチェックするために常に同期すると、一度に 1 つのスレッドがメソッドにアクセスできるようになり、何を犠牲にしてパフォーマンスの問題が発生するでしょうか? そのインスタンスを作成しようとしているスレッドが 2 つまたは 3 つしかないときに、プログラムの開始時に効率を高めるためです。

于 2013-04-14T03:59:52.810 に答える
0

is stillのgetInstance場合、複数のスレッドが呼び出される場合があります。instancenull

1 つのスレッドのみが同期ブロック (T1 としましょう) に入り、他のスレッドは待機します。

T1 が同期ブロックを終了すると、他のスレッドが開始されます。

がない場合はif (instance == null)、 の新しいインスタンスSingletonが作成されます。

于 2013-04-14T04:00:00.873 に答える
0

このコードは、並行性 (クラスを同時に使用する複数のスレッド) を想定しています。

コードは最初にインスタンスがあるかどうかを確認しようとします。存在しない場合は、作成を試みます。実行中に別のスレッドがそれを実行するのを避けるために、コードを でブロックしますsynchronized

ここで、最初のスレッドif (instance == null)と の間にsynchronized、別のより高速なスレッドが割り込んでインスタンスを作成した可能性があるため、コードは確認のために再度チェックします。

于 2013-04-14T04:00:10.993 に答える