簡單易懂設(shè)計(jì)模式 之 單例(Singleton)

one.jpg

單例模式概念并不復(fù)雜疲扎,其核心在于這個“單”字絮蒿,全局只有一個,無法創(chuàng)建多余一個的實(shí)例绩卤;單例模式在實(shí)際使用中很常見途样,是一種簡單卻實(shí)用的設(shè)計(jì)模式

使用場景

什么時候需要用到單例模式呢?我認(rèn)為主要有兩種情況

  1. 最好只有一個實(shí)例濒憋,即某個類在全局中只需要一個實(shí)例即可滿足需求何暇,再創(chuàng)建多余的實(shí)例既無必要,也浪費(fèi)資源凛驮,如一個全局的日志類裆站,或者Spring管理下的Bean默認(rèn)也是單例
  2. 應(yīng)該只有一個實(shí)例,即某個類的實(shí)例不應(yīng)該超過一個黔夭,否則有可能會產(chǎn)生問題宏胯,如一個數(shù)據(jù)庫連接池,全局就只應(yīng)該只有一個

總體來說纠修,當(dāng)某個類的實(shí)體類最好或應(yīng)該只有一個實(shí)例的時候胳嘲,就應(yīng)該考慮使用單例模式進(jìn)行代碼組織

代碼示例

單例模式比較常用的形式有兩種:饑漢模式與懶漢模式厂僧。這兩種模式的共同點(diǎn)在于都是通過私有化構(gòu)造方法來限制實(shí)例的創(chuàng)建扣草,它們的主要區(qū)別在于實(shí)例是預(yù)加載還是懶加載,一般來說建議使用懶加載的形式颜屠,畢竟有助于節(jié)省資源辰妙,提升效率;另外還有一種創(chuàng)建單例的形式甫窟,大家可能經(jīng)常會用到密浑,但不一定意識到自己其實(shí)寫了個單例,那就是Java的枚舉粗井,首先枚舉沒有課訪問的構(gòu)造器尔破,另外枚舉是通過公有的靜態(tài)final域?yàn)槊總€枚舉常量導(dǎo)出實(shí)例的類街图,這句話是什么意思呢?注意幾個重要的詞:靜態(tài)懒构,final餐济,實(shí)例的類,其實(shí)意思就是說每個枚舉常量都是一個靜態(tài)且final的類的實(shí)例胆剧,我想寫到這里大家應(yīng)該很容易能理解為什么說枚舉也是單例了絮姆,而且是一個final static的單例

  1. 饑漢模式(預(yù)加載)
public class EagerSingleton {
     private static EagerSingleton instance = new EagerSingleton();
    
     private EagerSingleton(){}
    
     public static EagerSingleton getInstance() {
          return instance;
     }
}
  1. 懶漢模式DCL版(懶加載)
public class LazySingleton {
     private volatile static LazySingleton instance;
    
     private LazySingleton(){}
    
     public static LazySingleton getInstance() {
          if(instance == null){
               synchronized(LazySingleton.class){
                    if(instance == null){
                         instance = new LazySingleton();
                    }
               }
          }
          return instance;
     }
}

在上述代碼示例的懶漢模式中,使用了DCL(Double checked Locking)秩霍,個人認(rèn)為這其實(shí)是一種不好的形式篙悯,假如不在instance實(shí)例前增加volatile聲明,那么將有可能會導(dǎo)致錯誤铃绒,即會導(dǎo)致:unsafe publication鸽照,什么意思呢,即在第一次check時颠悬,即便instance不是空移宅,但是也有可能此時的instance還未初始化完全,數(shù)據(jù)是不完整的椿疗,或錯的漏峰,而使用volatile在java 5.0之后雖然確實(shí)能避免這樣的問題,但是使得代碼形式顯得比較繁瑣届榄,同時DCL的主要目的在于盡量減少同步帶來的性能損耗浅乔,殊不知這種優(yōu)化基本可以忽略不計(jì),所以我建議一般采用下面簡單的寫法即可

  1. 懶漢模式簡化版(懶加載)
public class RegularSingleton {
    private static RegularSingleton instance;

    private RegularSingleton(){}

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

一個synchronized關(guān)鍵字即可铝条,不需要volatile靖苇,亦不需DCL

  1. 枚舉型單例
public enum ManKind {
    MAN {
        @Override
        void sad() {
            System.out.println("get a sleep");
        }
    },
    WOMAN {
        @Override
        void sad() {
            System.out.println("shopping");
        }
    };

    abstract void sad();
}

應(yīng)用實(shí)例

在JDK源碼中有很多對單例模式的使用,這里列舉幾個大家有興趣可以閱讀一下

  1. java.lang.Runtime#getRuntime()
  2. java.awt.Desktop#getDesktop()
  3. java.lang.System#getSecurityManager()
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末班缰,一起剝皮案震驚了整個濱河市贤壁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌埠忘,老刑警劉巖脾拆,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異莹妒,居然都是意外死亡名船,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進(jìn)店門旨怠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來渠驼,“玉大人,你說我怎么就攤上這事鉴腻∶陨龋” “怎么了百揭?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蜓席。 經(jīng)常有香客問我信峻,道長,這世上最難降的妖魔是什么瓮床? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任盹舞,我火速辦了婚禮,結(jié)果婚禮上隘庄,老公的妹妹穿的比我還像新娘踢步。我一直安慰自己,他們只是感情好丑掺,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布获印。 她就那樣靜靜地躺著,像睡著了一般街州。 火紅的嫁衣襯著肌膚如雪兼丰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天唆缴,我揣著相機(jī)與錄音鳍征,去河邊找鬼。 笑死面徽,一個胖子當(dāng)著我的面吹牛艳丛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播趟紊,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼氮双,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了霎匈?” 一聲冷哼從身側(cè)響起戴差,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎铛嘱,沒想到半個月后暖释,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡弄痹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年饭入,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肛真。...
    茶點(diǎn)故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖爽航,靈堂內(nèi)的尸體忽然破棺而出蚓让,到底是詐尸還是另有隱情乾忱,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布历极,位于F島的核電站窄瘟,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏趟卸。R本人自食惡果不足惜蹄葱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望锄列。 院中可真熱鬧图云,春花似錦、人聲如沸邻邮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽筒严。三九已至丹泉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鸭蛙,已是汗流浹背摹恨。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留娶视,地道東北人睬塌。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像歇万,于是被迫代替她去往敵國和親揩晴。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評論 2 355

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