研究ノート:シングルトンモード

シングルトンモード:シングルトンモードとは何ですか?薄暗いいつ使用されますか?なぜそれを使うのですか?それを使用する方法?最初に5回連続で品質の波が来ます

それは何ですか?

シングルトンモード?文字通り理解されている、単一:1、例:インスタンス、これは私たちがオブジェクトと呼んでいるものです

使用は何ですか?

リソースを再利用するためのもので、一度割り当てるか初期化するだけで、誰でも再利用できます

いつ使用されますか?なぜそれを使うのですか?(カレンダーなど1つ、IOCコンテナなど1つのみ)

リスナーリスナー、カレンダーカレンダークラス、IOCコンテナクラス、構成情報Config(1回の移動はシングルトン)、これらはすべてシングルトンです

それを使用する方法?(一言も言えないので、丁寧に話させてください)

以下では、空腹のスタイル、怠惰なスタイル、最も強力なシングルトンモード、列挙、登録逆シリアル化、シングルトンおよびその他のシングルトンモードを確実にする方法を使用して詳細に説明します 

 

  1. 空腹の中国風(シングルトンを実現することを不可能にする明らかな間違いがあります、答えは次のテキストに隠されています)

空腹のチャイニーズスタイルとは何ですか?私の理解では、お腹が空いたときに食べるのが待ちきれません。以下のコードの9行目を見てください。

private static final:クラスがロードされたときにオブジェクトが初期化され、次に静的になることを示します。したがって、オブジェクトはプログラムが停止するまで保持されます。

短所:当然、このオブジェクトを使用するかどうかに関係なく、このクラスをロードするときに初期化され、プログラムが停止するまでスペースを占有します。

利点:明らかに、クラスがロードされるときに初期化されるため、オブジェクトの作成時に同時実行の問題がありません。つまり、スレッドセーフの問題がなく、シングルトンが保証され、効率が悪くない必要があります。オブジェクトの作成時に作成されますこれらの数ナノ秒を保存します

推奨されるアプリケーションシナリオ:特定のクラスのオブジェクトのコピーが1つだけ必要で、それを頻繁に使用する場合は、このモードを使用できます。

 

  1. 怠惰な男のスタイル(明示的に、答えは下の写真にあります)

怠惰な男のスタイルとは何ですか?私の理解では、怠惰な人の特徴を理解するとき、事前に何かを準備するために急ぐ必要はなく、必要なときにだけ準備する必要があります。

レイジーモードのオブジェクトは、必要に応じてメソッドを呼び出すことで取得でき、シングルトンを保証できることがわかります(保証できますか?)。長所と短所の分析を続けましょう。

利点:メモリの浪費を回避し、オブジェクトが必要な場合にのみ取得し、基本的に同時実行性が高くない場合にシングルトンを保証します

短所:明らかに、同時実行性が高くない場合はシングルトンを保証できますが、同時実行性が高くない場合は特定のシングルトンを保証できません。解決方法として、メソッドの前に同期キーワードを追加します(パフォーマンス要件は高くありません。追加できます。結局のところ、同期ロックは待機する必要があります。理解できない場合は、同期された同期ロックについて学ぶことができます)

  1. 上記には多かれ少なかれ欠点があるので、ここに怠惰なスタイルの改良版があります(つまり、タイトルの最も強力なバージョンです。私をタイトルファイルと呼ばないでください...)

利点:空腹の人モードのメモリ使用量の問題と同期のパフォーマンスの問題の両方(私はパフォーマンスをテストしました、200Wオブジェクトを作成する速度は基本的に空腹の人モードと同じです)、テストコードは投稿されません、自分で試してみてください

短所:メッセージを残すことを歓迎します

登録された単純な利息

登録されたシングルトンモードは、階層型シングルトンモードとも呼ばれ、特定の場所に各インスタンスを登録し、一意の識別子を使用してインスタンスを取得します。登録されているシングルトンiモードは2つあります。1つは列挙型シングルトンモードで、もう1つはコンテナシングルトンモードです。

1.列挙型シングルトンモード

  列挙型シングルトンモードは次のように記述されます。

コードをコピーする

public enum EnumSingleton {
    INSTANCE;
    private Object data;
    public Object getData() {
        return data;
    }
    public void setData(Object data) {
        this.data = data;
    }
    public static EnumSingleton getInstance(){
        return INSTANCE;
    }
}

コードをコピーする

  テストコードは次のとおりです。

コードをコピーする

    @Test
    void EnumSingletonTest(){
        EnumSingleton e1 = null;
        EnumSingleton e2 = EnumSingleton.getInstance();
        e2.setData(new Object());
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream("EnumSingleton.obj");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(e2);
            oos.flush();
            oos.close();

            FileInputStream fis = new FileInputStream("EnumSingleton.obj");
            ObjectInputStream ois = new ObjectInputStream(fis);
            e1 = (EnumSingleton)ois.readObject();
            ois.close();
            System.out.println(e1.getData());
            System.out.println(e2.getData());
            System.out.println(e1.getData() == e2.getData());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

コードをコピーする

  結果は次のとおりです。

  列挙型は、実際にはクラス名とクラスオブジェクトを介して一意の列挙オブジェクトを検索します。したがって、列挙オブジェクトをクラスローダーによって複数回ロードすることはできません。

  それで、反射は列挙されたシングルトンパターンを破壊することができますか?テストコードは次のとおりです。

コードをコピーする

    @Test
     void EnumSingletonTestThread() {
        try{
            Class clazz = EnumSingleton.class;
            Constructor c = clazz.getDeclaredConstructor();
            c.newInstance();
        } catch (Exception e){
            e.printStackTrace();
        }
    }

コードをコピーする

  結果は次のとおりです。

 エラーにより、引数のない構築方法が見つかりませんでした。列挙型ソースコードの表示彼の構築メソッドには、保護されたタイプの構築メソッドが1つだけあり、コードは次のとおりです。

  protected Enum(String name、int ordinal){this.name = name; this.ordinal = ordinal; }  

  次のテストを再度実行します。

コードをコピーする

    @Test
     void EnumSingletonTestThread() {
        try{
            Class clazz = EnumSingleton.class;
            Constructor c = clazz.getDeclaredConstructor(String.class,int.class);
            c.setAccessible(true);
            EnumSingleton enumSingleton = (EnumSingleton)c.newInstance("l-coil",666);
        } catch (Exception e){
            e.printStackTrace();
        }
    }

コードをコピーする

   テスト結果は次のとおりです。

  

  エラーはすでに明らかであり、リフレクションを使用して列挙型を作成することはできません。

  列挙されたシングルトンモードは、EffectiveJavaの本に書かれている一種のシングルトンモードの実装でもあります。JDK列挙の特別な文法的性質と再現も列挙引用をエスコートし、列挙シングルトンモードをよりエレガントな実装にします。 

2.コンテナシングルトン

  コンテナシングルトンは次のように記述されます。

コードをコピーする

public class ContainerSingleton {
    private ContainerSingleton(){}
    private static Map<String,Object> ioc = new ConcurrentHashMap<String,Object>();
    public static Object getBean(String className){
        synchronized (ioc){
            if(!ioc.containsKey(className)){
                Object obj = null;
                try{
                    obj = Class.forName(className).newInstance();
                    ioc.put(className, obj);
                }catch (Exception e){
                    e.printStackTrace();
                }
                return obj;
            } else {
              return ioc.get(className);
            }
        }
    }
}

コードをコピーする

  コンテナスタイルのシングルトンモードは、多くの場合、編集管理で使用されます。スレッドセーフではありません。

おすすめ

転載: blog.csdn.net/My_SweetXue/article/details/111608549