設(shè)計模式讀書筆記之單例模式

單例模式是確保一個類只有實例僚害,而且自行實例化并向整個系統(tǒng)提供實例禽绪。它可能是應(yīng)用使用最廣泛的模式闸度,也是最廣為人知的一種設(shè)計模式猾骡,就連我這個菜逼提到單例模式也能說上兩句瑞躺,蹦出懶漢模式敷搪,餓漢模式這樣的名詞。

那它究竟是怎么樣的幢哨,又有多少種呢赡勘,又是在怎樣的場景中使用呢?
我們先來看看它的使用場景捞镰,如上所說闸与,它是確保一個類有且只有一個實例對象,避免產(chǎn)生多個對象消耗過多資源或某種對象只應(yīng)該有且只有一個的場景岸售,比如訪問io或數(shù)據(jù)庫的這樣比較消耗的對象践樱。

角色介紹:
(1)Client--高層客戶端

(2)SingLecton--單例類
實現(xiàn)單列模式的關(guān)鍵點:
1.構(gòu)造函數(shù)不對外開放,用private來修飾
2.通過一個靜態(tài)方法或枚舉來返回對象
3.確保單例對象有且只有一個凸丸,尤其是在多線程情況下
4.確保單例對象不會在反序列化里重構(gòu)對象拷邢。
通過單例類的構(gòu)造函數(shù)私有化使得客戶端不能通過new的形式來手動構(gòu)造單例類的對象,只能通過單例對象暴露的靜態(tài)方法獲取到單例對象的唯一對象屎慢,同時在獲取到這個唯一的對象時候也要保證線程的安全解孙,即在多線程環(huán)境下也要保證構(gòu)造的單例對象有且只有一個,這也是單例模式里實現(xiàn)比較困難的地方抛人。
下面用代碼來看看幾種單例模式的表現(xiàn)形式吧。
1.餓漢模式

public class Singleton {
    private static Singleton instance = new Singleton();
    private Singleton(){

    }

    public static Singleton getInstance(){
        return instance;
    }

餓漢模式將對象構(gòu)造函數(shù)私有化脐瑰,不能通過new獲取妖枚,而我們將對象設(shè)為靜態(tài),并在聲明的時候初始化苍在。只能通過靜態(tài)方法獲取绝页,保證了對象的唯一性。
2.懶漢模式(線程不安全寂恬,不推薦)

public class Singleton {
    private static Singleton instance;

    private Singleton() {

    }

    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }

該模式添加了關(guān)鍵字synchronized說明是同步方法续誉,保證了在多線程模式下對象唯一的手段。問題在于初肉,第一次調(diào)用初始化后
每次調(diào)用getInstance()方法仍會進行同步酷鸦,會消耗不必要資源,一般不推薦
總結(jié)懶漢模式下優(yōu)點在于只有被調(diào)用的時候才會去實例化牙咏,在一定程度上節(jié)約了資源臼隔,缺點是第一次調(diào)用加載及時實例化,反應(yīng)稍慢妄壶,每次調(diào)用的
時候會同步摔握,增加不必要的同步開銷。
3.DCL模式

public class Singleton {
    private static Singleton instance=null;

    private Singleton() {

    }
    public static Singleton getInstance(){
        if (instance==null){
            synchronized (Singleton.class){
                if (instance==null){
                    instance=new Singleton();
                }
            }
        }
        return instance;
    }

程序亮點在于getInstance方法上丁寄,在此方法里對instance進行兩次判空氨淌,第一次是為了避免不必要的同步泊愧,第二次判空 是為了在null的情況下創(chuàng)建實例。解決了資源消耗盛正,多余同步删咱,線程安全問題。
更詳細的解釋:
假設(shè)線程A執(zhí)行到 instance=new Singleton()的時候蛮艰,它大致做了三件事情:
給Singleton實例分配內(nèi)存腋腮,
調(diào)用構(gòu)造函數(shù),初始化字段
將instance對象指向分配的內(nèi)存空間(此時Singlecton已經(jīng)不為null)

DCL的優(yōu)點:資源利用率高壤蚜,效率高
缺點:第一次加載反應(yīng)稍慢即寡,由于java內(nèi)存模型的原因偶爾會失敗,在高并發(fā)環(huán)境下有一定缺陷(概率很型嗨ⅰ)聪富。DCL是單例使用最多的模式。
4.靜態(tài)內(nèi)部內(nèi)模式

public class Singleton {


    private Singleton() {

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

    public static class SingletonHoulder{
        private static final Singleton instance = new Singleton();
    }

靜態(tài)內(nèi)部內(nèi)方式靜態(tài)內(nèi)部內(nèi)模式著蟹,是為了防止dcl模式在某些情況下失效(雙重鎖定失效)而產(chǎn)生出來的墩蔓。
5.枚舉模式

public enum Singleton {  
     INSTANCE;  
     public void whateverMethod() {  
     }  
 }  

這種方式是Effective Java作者Josh Bloch 提倡的方式,它不僅能避免多線程同步問題萧豆,而且還能防止反序列化重新創(chuàng)建新的對象奸披。
6.容器模式

public class SinglectonManager {
    private static Map<String,Object> objectMap = new HashMap<String, Object>();
    private SinglectonManager(){
    }
    private static void resgisterService(String key,Object instance){
        if (!objectMap.containsKey(key)){
            objectMap.put(key,instance);
        }
    }
    public static Object getService(String key){
       return objectMap.get(key);
    }
}

在程序初始時,將多種單例類型注入到一個統(tǒng)一管理類中涮雷,在使用時候根據(jù)key獲取對應(yīng)的對象阵面,這種方式可讓我們管理多種類型,并在
獲取時候可以通過統(tǒng)一接口獲取洪鸭,降低使用成本样刷,也隱藏了具體實現(xiàn),降低了耦合览爵。

總結(jié):
優(yōu)點:
1.單例模式在內(nèi)存中只有一個實例置鼻,減少了內(nèi)存的開支,尤其是當一個對象頻繁創(chuàng)建銷毀蜓竹,而創(chuàng)建銷毀時性能無法優(yōu)化優(yōu)勢最為明顯
2.減少系統(tǒng)性能開銷箕母,當一個對象產(chǎn)生需要較多資源時候,讀取配置俱济,依賴對象時候司蔬,可以使其直接產(chǎn)生一個單例,然后永久駐留內(nèi)存的方式解決姨蝴。
3.避免對資源文件的多重占用
4.優(yōu)化和共享資源訪問

缺點:
1.沒有接口俊啼,擴展困難
2.如果持有Context,容易引發(fā)內(nèi)存泄露(最好是ApplicationContext)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末左医,一起剝皮案震驚了整個濱河市授帕,隨后出現(xiàn)的幾起案子同木,更是在濱河造成了極大的恐慌,老刑警劉巖跛十,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件彤路,死亡現(xiàn)場離奇詭異,居然都是意外死亡芥映,警方通過查閱死者的電腦和手機洲尊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來奈偏,“玉大人坞嘀,你說我怎么就攤上這事【矗” “怎么了丽涩?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長裁蚁。 經(jīng)常有香客問我矢渊,道長,這世上最難降的妖魔是什么枉证? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任矮男,我火速辦了婚禮,結(jié)果婚禮上室谚,老公的妹妹穿的比我還像新娘毡鉴。我一直安慰自己,他們只是感情好舞萄,可當我...
    茶點故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著管削,像睡著了一般倒脓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上含思,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天崎弃,我揣著相機與錄音,去河邊找鬼含潘。 笑死饲做,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的遏弱。 我是一名探鬼主播盆均,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼漱逸!你這毒婦竟也來了泪姨?” 一聲冷哼從身側(cè)響起游沿,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎肮砾,沒想到半個月后诀黍,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡仗处,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年眯勾,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片婆誓。...
    茶點故事閱讀 40,861評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡吃环,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出旷档,到底是詐尸還是另有隱情模叙,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布鞋屈,位于F島的核電站范咨,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏厂庇。R本人自食惡果不足惜渠啊,卻給世界環(huán)境...
    茶點故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望权旷。 院中可真熱鬧替蛉,春花似錦、人聲如沸拄氯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽译柏。三九已至镣煮,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鄙麦,已是汗流浹背典唇。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留胯府,地道東北人介衔。 一個月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像骂因,于是被迫代替她去往敵國和親炎咖。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,860評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 單例模式(SingletonPattern)一般被認為是最簡單、最易理解的設(shè)計模式塘装,也因為它的簡潔易懂急迂,是項目中最...
    成熱了閱讀 4,257評論 4 34
  • 前言 本文主要參考 那些年,我們一起寫過的“單例模式”蹦肴。 何為單例模式僚碎? 顧名思義,單例模式就是保證一個類僅有一個...
    tandeneck閱讀 2,517評論 1 8
  • 一.什么是單例模式 單例模式的定義:確保一個類只有一個實例阴幌,并提供一個訪問他的全局訪問點勺阐。單例模式是幾個設(shè)計模式中...
    Geeks_Liu閱讀 2,230評論 0 10
  • 概述 單例模式是應(yīng)用最廣的模式之一,在應(yīng)用這個模式時矛双,單例對象的類必須保證只有一個實例存在渊抽。許多時候整個系統(tǒng)只需要...
    劉滌生閱讀 1,022評論 0 5
  • 1.單例模式概述 (1)引言 單例模式是應(yīng)用最廣的模式之一,也是23種設(shè)計模式中最基本的一個议忽。本文旨在總結(jié)通過Ja...
    曹豐斌閱讀 2,944評論 6 47