小談単例モード


単一の例のモードは一般的な設計モードであり、グローバルに1つのインスタンスしかないことを保証するには、この最も基本的な条件を保証するために、静的な作成方法を提供し、参照としなければならない.ここで興味深い2つの行動パターンが現れます.餓漢式単例モードと怠け者式単例モードです.この2つの方法にはどんな違いがありますか?辛い麺のブログからその例を取って説明します.
public class Singleton {
        private Singleton(){}
        private static Singleton instance = new Singleton();
        public static Singleton getInstance() {
        return instance;
        }
    }

これはよく使われる餓漢式の単例モードであり、非常に理解しやすい.つまり、クライアント呼び出し方法:Singleton.getInstance()はこのインスタンスを使用することができ、唯一のインスタンスである.このような使用方法には何の制限もなく、どのクライアントもこの文を使用すれば必ずインスタンスを作成することができる.JAVA言語から言えば、この方式は最も単例のモードを表現することができる.同様に、怠け者の単例モードが依然として辛い麺を使用している例を説明します.
public class Singleton {
        private Singleton(){}
        private static Singleton instance = null;
        public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
        }
    }

これも単一のパターンですが、作成時にスレッド表示synchronizedを使用し、作成時に作成された餓漢式とは異なります.
if (instance == null) {
       instance = new Singleton();
}

的判断これは何の役に立つのですか.ほほほ、少し基礎の良い友达は一目で見るべきで、それはクライアントの呼び出しの時に制限があって、つまり静的なクライアントの方法の中でこの単例のクラスに対して実例化することができません.(もちろんsynchronizedはif(instance==null)のために使われています)実は彼らの違いもそれほど大きくなく、ただの制限の問題なので、このデザインモードを使う際にJAVAモードの観点から、私は餓漢式を使う傾向があります.ここではいわゆるdouble-checked(二重検出)についても少しお話ししますが、まず怠け者式は二重検出の技術を使用していないことを明らかにしますが、二重検出はC++言語でよく使われるテクニックの一つで、怠け者式の改造といえば、方法の表示synchronizedを除去し、方法体でif(instance==null)を判断してsynchronized{}を使用します.一方synchronized{}ではif(instance==null)を再度判断する、二重検出の目的を達成する.しかし残念ながらこの二重検査はJAVAのコンパイラに対して成立しないで、instanceの検査と彼の申明に対して時間の上で厳格な前後の順序がないため、コンパイラは先に検査してから申明して崩壊を招くかもしれない.