2 番目の例では、誰かが言及したように、スレッド セーフではありません。getInstance() メソッドをスレッドセーフにするための 2 つのオプションを次に示します。
public static synchronized Singleton getInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
public static Singleton getInstance() {
if (singleton == null) {
synchronized(Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
メソッドの 2 番目のバージョンでは、同期のオーバーヘッドなしで、既に構築されたシングルトン インスタンスを取得できます。ただし、null の場合は、同期ブロックに入ります。スレッド コンテキスト スイッチがあり、2 番目のスレッドが実際に同期ブロックに入った場合に備えて、もう一度 null をチェックします。これにより、単一のインスタンスのみが構築されることが保証されます。
いずれのアプローチも、完全にスレッド セーフである必要があります。