3

典型的なレイジーシングルトン:

public class Singleton {
    private static Singleton INSTANCE;

    private Singleton() {

    }

    public static synchronized Singleton getInstace() {
        if(INSTANCE == null)
            INSTANCE = new Singleton();

        return INSTANCE;
    }
}

典型的な熱心なシングルトン:

public class Singleton {
    private static Singleton INSTANCE = new Singleton();

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

熱心なシングルトンとの同期について心配しないのに、怠惰ないとことの同期について心配する必要があるのはなぜですか?

4

3 に答える 3

1

熱心なインスタンス化では、フィールドの参照を共有するための明示的な同期は必要ありません。これは、JVMがクラス読み込みメカニズムの一部としてすでにフィールドの参照を処理しているためです。

より詳細に説明すると、クラスがスレッドで使用できるようになる前に、クラスがロードされ、検証され、初期化されます。コンパイラは、静的フィールドの割り当てをこの初期化段階に書き換え、Javaメモリモデルのルールと基盤となるハードウェアアーキテクチャを介して、そのクラスにアクセスするすべてのスレッドがこのバージョンのクラスを確実に認識できるようにします。これは、JVMがハードウェアバリアなどを処理してくれることを意味します。

そうは言っても、熱心な初期化を最終的にマークすることをお勧めします。これにより、意図が明確になり、コンパイラーは、熱心な初期化が変更されないように強制します。もしそうなら、同時実行制御が再び必要になるでしょう。

private static **final** Singleton INSTANCE = new Singleton();

参考までに、興味があれば、Java仮想マシン仕様のセクション5.5でこれについてさらに詳しく説明しています。仕様からのいくつかの選択スニペットは次のとおりです。

*"Because the Java Virtual Machine is multithreaded, 
initialization of a class or interface requires careful 
synchronization"*

*"For each class or interface C, there is a unique initialization lock LC"*

*9&10) "Next, execute the class or interface initialization method of C"
"If the execution of the class or interface initialization 
method completes normally, then acquire LC, label the Class object for 
C as fully initialized, notify all waiting threads, release LC, and 
complete this procedure normally."*

静的フィールドが設定されるのは仕様のステップ10であり、ロック(LC)を使用して、1つのスレッドのみが初期化を実行し、結果が正しく共有されるようにします。

于 2013-03-03T11:56:33.973 に答える
0

熱心なシングルトンは、クラスが最初にメモリ(jit)にロードされたときに初期化されるため、これは1回だけ発生します。ただし、2つのクライアントが同時に2つのスレッドからシングルトンインスタンスメソッドを呼び出そうとすると、2つのシングルトンが作成される可能性があります。

于 2013-03-02T19:22:58.063 に答える
0

後者の例では、getInstanceが呼び出されたときにシングルトンのインスタンスが常に存在するため、ここで同期するものはありません。これは、インスタンスがまだ初期化されている必要がない最初の例とは対照的です。この場合、には、同時アクセスから(同期などによって)保護する必要のあるgetInstanceクリティカルセクション(およびその本体)が含まれます。if

于 2013-03-02T19:26:49.427 に答える