ここでの最近の質問には、同期なしでシングルトンを実装するための次のコード(まあ、これに似ています)がありました。
public class Singleton {
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
今、私はこれが何をしているのか理解していると思います。インスタンスはstatic final
であるため、スレッドが呼び出されるずっと前にビルドされgetInstance()
、同期の実際の必要はありません。
getInstance()
同期が必要になるのは、2つのスレッドが同時に呼び出そうとした場合のみです(そして、そのメソッドは、"static final"
時間ではなく最初の呼び出しで構築を行いました)。
したがって、私の質問は基本的に次のとおりです。なぜ、次のようなシングルトンの怠惰な構築を好むのでしょうか。
public class Singleton {
private Singleton() {}
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
if (instance == null)
instance = new Singleton();
return instance;
}
}
私の唯一の考えは、このstatic final
メソッドを使用すると、C++の静的初期化順序の大失敗のようにシーケンスの問題が発生する可能性があるということでした。
まず、Javaには実際にこの問題がありますか?クラス内の順序が完全に指定されていることは知っていますが、クラス間で一貫した順序が保証されていますか(クラスローダーなど)?
第二に、順序が一貫している場合、なぜ怠惰な構築オプションが有利になるのでしょうか?