Javaにおけるシングルトンパターンの実装方法は何ですか?
Javaのシングルトンパターンの実装方法には以下のいくつかの方法があります。
- 懒漢式(Lazy Initialization):
インスタンスを初めて使用するときに作成されます。スレッドセーフでないバージョンの懒漢式の実装は以下のようになります:
public class Singleton {
private static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
getInstance()メソッドにsynchronizedを追加してスレッドセーフの遅延初期化シングルトンパターンを実装することができますが、効率に影響を与える可能性があります。
public class Singleton {
private static Singleton instance;
private Singleton(){}
public static synchronized Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
- イーガーイニシャライゼーション:
クラスの読み込み時にインスタンスを作成し、スレッドセーフ。実装は以下の通りです。
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return instance;
}
}
クラスのロード時にインスタンスが作成されるため、遅延ロードはできません。
- ダブルチェックロック(Double Checked Locking)は、遅延初期化として、スレッドセーフと効率の高さを確保するために、二重チェックを行います。
public class Singleton {
private volatile static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
synchronized (Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
instance変数にvolatile修飾子を使用すると、マルチスレッド環境での可視性と順序性が保証されます。
- 静的な内部クラスを使用して、遅延読み込みとスレッドセーフを実現する懒汉式にします。
public class Singleton {
private Singleton(){}
private static class SingletonHolder{
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance(){
return SingletonHolder.INSTANCE;
}
}
静的な内部クラスは、初めて使用されるときにのみ読み込まれるため、遅延読み込みが実現されます。
- 列挙型(Enum):
列挙型クラスを使用してシングルトンパターンを実装すると、スレッドセーフとリフレクション攻撃を防ぐことができます。
public enum Singleton {
INSTANCE;
public void doSomething(){
// do something
}
}