Javaにおけるシングルトンパターンの実装方法は何ですか?

Javaのシングルトンパターンの実装方法には以下のいくつかの方法があります。

  1. 懒漢式(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;
    }
}
  1. イーガーイニシャライゼーション:
    クラスの読み込み時にインスタンスを作成し、スレッドセーフ。実装は以下の通りです。
public class Singleton {
    private static Singleton instance = new Singleton();

    private Singleton(){}

    public static Singleton getInstance(){
        return instance;
    }
}

クラスのロード時にインスタンスが作成されるため、遅延ロードはできません。

  1. ダブルチェックロック(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修飾子を使用すると、マルチスレッド環境での可視性と順序性が保証されます。

  1. 静的な内部クラスを使用して、遅延読み込みとスレッドセーフを実現する懒汉式にします。
public class Singleton {
    private Singleton(){}

    private static class SingletonHolder{
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance(){
        return SingletonHolder.INSTANCE;
    }
}

静的な内部クラスは、初めて使用されるときにのみ読み込まれるため、遅延読み込みが実現されます。

  1. 列挙型(Enum):
    列挙型クラスを使用してシングルトンパターンを実装すると、スレッドセーフとリフレクション攻撃を防ぐことができます。
public enum Singleton {
    INSTANCE;

    public void doSomething(){
        // do something
    }
}
bannerAds