#CHALLENGE_1001 - 單例模式

  1. best practice: Sinigleton w/ enum
public enum Singleton {  
    INSTANCE;  
    public void whateverMethod() {  
    }  
}  
  • pro:
    • concise, and thread-safe.
    • enum is singleton by design. All the enum values are initialized only once when class loaded.
    • enum 支持反序列化機制巾陕,無需實現(xiàn) Serializable 接口和重寫 readResolve() 方法怕敬,即可避免反序列化中對單例模式的破壞。
    • enum can’t be initialized via reflection. 試圖通過反射方式得到單例對象屏歹,會報錯:java.lang.IllegalArgumentException: Cannot reflectively create enum objects.
  • con: none.
  1. Traditional Methods of Making Singletons:
    2.1 : Eagerly Initialized Singleton
public class EagerSingleton {

    /** private constructor to prevent others from instantiating this class */
    private EagerSingleton() {}

    /** Create an instance of the class at the time of class loading */
    private static final EagerSingleton instance = new EagerSingleton();

    /** Provide a global point of access to the instance */
    public static EagerSingleton getInstance() {
        return instance;
    }
}
  • pro: thread-safe.
  • con: the instance is created irrespective of whether it is accessed or not. This is fine if the object is simple and does not hold any system resources. But can have performance implications if it allocates a large amount of system resources and remains unused.

2.2 : Eagerly Initialized Static Block Singleton

public class EagerStaticBlockSingleton {

    private static final EagerStaticBlockSingleton instance;

    /** Don't let anyone else instantiate this class */
    private EagerStaticBlockSingleton() {}

    /** Create the one-and-only instance in a static block */
    static {
      instance = new EagerStaticBlockSingleton();
    }

    /** Provide a public method to get the instance that we created */
    public static EagerStaticBlockSingleton getInstance() {
        return instance;
    }
}
  • pro:thread-safe.
  • con:the instance is created whether or not it is needed by the application.

2.3 : Lazily Initialized Singleton

public class LazySingleton {

    private static LazySingleton instance;

    /** Don't let anyone else instantiate this class */
    private LazySingleton() {}

    /** Lazily create the instance when it is accessed for the first time */
    public static synchronized LazySingleton getInstance() {
        if(instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}
  • pro:The synchronized keyword ensures thread-safety.
  • con:The synchronized solution is kinda inefficient.

2.4 : Lazily Initialized Double-Checked Locking Singleton

public class LazyDoubleCheckedLockingSingleton {

    private static volatile LazyDoubleCheckedLockingSingleton instance;

    /** private constructor to prevent others from instantiating this class */
    private LazyDoubleCheckedLockingSingleton() {}

    /** Lazily initialize the singleton in a synchronized block */
    public static LazyDoubleCheckedLockingSingleton getInstance() {
        if(instance == null) {
            synchronized (LazyDoubleCheckedLockingSingleton.class) {
                // double-check
                if(instance == null) {
                    instance = new LazyDoubleCheckedLockingSingleton();
                }
            }
        }
        return instance;
    }
}
  • pro:the use of volatile keyword is necessary here to prevent compilers from doing their own optimizations (like instruction reordering). and it's thread-safe.
  • con:not very efficient.

2.5 Lazily Initialized Inner Class Singleton

public class LazyInnerClassSingleton {

    /** private constructor to prevent others from instantiating this class */
    private LazyInnerClassSingleton() {}

    /** This inner class is loaded only after getInstance() is called for the first time. */
    private static class SingletonHelper {
        private static final LazyInnerClassSingleton INSTANCE = new LazyInnerClassSingleton();
    }

    public static LazyInnerClassSingleton getInstance() {
        return SingletonHelper.INSTANCE;
    }
}
  • pro: most efficient due to the reason that the inner class is not loaded until the getInstance() method is invoked for the first time. This solution is thread-safe and doesn’t require any other synchronization.
  • con: none.

Conclusion:

  • The examples above are several thread-safe ways of implementing the singleton design pattern. (who would want thread-unsafe solutions?)
  • Last but not the least, 簡單描述一下單例模式的應(yīng)用場景:
    單例模式能保證在一個JVM中揭北,對象只有一個實例存在。正是由于這個特點吏颖,單例對象通常作為程序中的存放配置信息的載體搔体,因為它能保證其他對象讀到一致的信息。例如在某個服務(wù)器程序中半醉,該服務(wù)器的配置信息可能存放在數(shù)據(jù)庫或文件中疚俱,這些配置數(shù)據(jù)由某個單例對象統(tǒng)一讀取,服務(wù)進(jìn)程中的其他對象如果要獲取這些配置信息缩多,只需訪問該單例對象即可呆奕。這種方式極大地簡化了在復(fù)雜環(huán)境下养晋,尤其是多線程環(huán)境下的配置管理,但是隨著應(yīng)用場景的不同梁钾,也可能帶來一些同步問題绳泉。我們具體問題具體分析吧。

EOF

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末姆泻,一起剝皮案震驚了整個濱河市零酪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌拇勃,老刑警劉巖四苇,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異方咆,居然都是意外死亡月腋,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進(jìn)店門瓣赂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來榆骚,“玉大人,你說我怎么就攤上這事钩述≌辏” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵牙勘,是天一觀的道長职恳。 經(jīng)常有香客問我,道長方面,這世上最難降的妖魔是什么放钦? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮恭金,結(jié)果婚禮上操禀,老公的妹妹穿的比我還像新娘。我一直安慰自己横腿,他們只是感情好颓屑,可當(dāng)我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著耿焊,像睡著了一般揪惦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上罗侯,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天器腋,我揣著相機與錄音,去河邊找鬼。 笑死纫塌,一個胖子當(dāng)著我的面吹牛诊县,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播措左,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼依痊,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了媳荒?” 一聲冷哼從身側(cè)響起抗悍,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎钳枕,沒想到半個月后缴渊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡鱼炒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年衔沼,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片昔瞧。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡指蚁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出自晰,到底是詐尸還是另有隱情凝化,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布酬荞,位于F島的核電站搓劫,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏混巧。R本人自食惡果不足惜枪向,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望咧党。 院中可真熱鬧秘蛔,春花似錦、人聲如沸傍衡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蛙埂。三九已至辨液,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間箱残,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留被辑,地道東北人燎悍。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像盼理,于是被迫代替她去往敵國和親谈山。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,675評論 2 359