シングルトンパターンは、クラスが 1 つのインスタンスしか持たないことを保証し、グローバルなアクセスポイントを提供します。
Java では、シングルトンパターンを実装するために次のような一般的な方法があります。
饿漢式#
饿漢式は、クラスのロード時にインスタンスを作成し、スレッドセーフですが、メモリを浪費する可能性があります。
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
// コンストラクタをプライベート化して外部からのインスタンス化を防止
private Singleton() {}
// グローバルなアクセスポイントを提供
public static Singleton getInstance() {
return INSTANCE;
}
}
スレッドセーフでない懒漢式#
懒漢式は、getInstance()
が最初に呼び出されたときにインスタンスを作成し、スレッドセーフではありません。
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
スレッドセーフな懒漢式#
同期メソッドを使用して、マルチスレッド環境でも 1 つのインスタンスしか存在しないことを保証します。
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 volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
静的内部クラス#
静的内部クラスを使用して、スレッドセーフで遅延ロードを実現します。
public class Singleton {
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
列挙型#
最もシンプルな実装方法であり、推奨されます。スレッドセーフであり、シリアライズをサポートし、リフレクション攻撃を防ぐことができます。
public enum Singleton {
INSTANCE;
public void someMethod() {
// インスタンスメソッド
}
}