シングルケースモード(Head First版)
2045 ワード
≪単一モード|Single Mode|emdw≫:クラスにインスタンスが1つしかないことを確認し、グローバル・アクセス・ポイントを提供します.
コード実装:
上記の例では,高同時の場合,2つのインスタンスが生成される可能性が高い.
スレッドがsingleton=new Singleton()に入り、まだインスタンス化されていません.
もう1つのスレッドはsingleton==nullでtrueです.これにより2つのインスタンスが生成されます
上のgetInstanceメソッドに同期ブロックを追加します.次のように
これにより、1つのインスタンスのみが生成されることが保証されますが、高同時性の場合、この方法はパフォーマンスに問題があります.
修正を続けsingleton変数にvolatile修飾を加える
また、同期ブロックは、最初のインスタンス化時にのみ入力され、同期のパフォーマンスの問題が解決されます.
なぜsingletonをグローバルな静的変数として定義しないのか、以下のようにします.
public static Singleton singleton = new Singleton();
このように書くと,Singletonが初期化されると,この変数はインスタンス化され,すなわち急に確実にインスタンス化される.
上記の例とは異なり、この変数を実際に使用した場合にのみインスタンス化されます.
Volatile変数は
volatileの使用には明確な規定があります.
変数の書き込み操作は現在の値に依存しません.
この変数は、他の変数を有する不変式に含まれていない.
コード実装:
package com.headfirst.chapter5;
public class Singleton {
private static Singleton singleton;
private Singleton(){}
public static Singleton getInstance(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
上記の例では,高同時の場合,2つのインスタンスが生成される可能性が高い.
スレッドがsingleton=new Singleton()に入り、まだインスタンス化されていません.
もう1つのスレッドはsingleton==nullでtrueです.これにより2つのインスタンスが生成されます
上のgetInstanceメソッドに同期ブロックを追加します.次のように
package com.headfirst.chapter5;
public class Singleton {
private static Singleton singleton;
private Singleton(){}
public static synchronized Singleton getInstance(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
これにより、1つのインスタンスのみが生成されることが保証されますが、高同時性の場合、この方法はパフォーマンスに問題があります.
修正を続けsingleton変数にvolatile修飾を加える
また、同期ブロックは、最初のインスタンス化時にのみ入力され、同期のパフォーマンスの問題が解決されます.
package com.headfirst.chapter5;
public class Singleton {
private volatile static Singleton singleton;
private Singleton(){}
public static Singleton getInstance(){
if(singleton == null){
synchronized(Singleton.class){
if(singleton == null){
singleton = new Singleton();
}
}
}
return singleton;
}
なぜsingletonをグローバルな静的変数として定義しないのか、以下のようにします.
public static Singleton singleton = new Singleton();
このように書くと,Singletonが初期化されると,この変数はインスタンス化され,すなわち急に確実にインスタンス化される.
上記の例とは異なり、この変数を実際に使用した場合にのみインスタンス化されます.
Volatile変数は
synchronized
の可視性特性を持つが,原子特性は備えていない.すなわち、スレッドはvolatile変数の最新値を自動的に発見することができる.volatileの使用には明確な規定があります.
変数の書き込み操作は現在の値に依存しません.
この変数は、他の変数を有する不変式に含まれていない.