「碼唄學(xué)院」單例模式你知道有幾種寫法萄喳?

茴香豆的“茴”字有幾種寫法蹋半?

有一回對我說道,“你讀過書么染突?”我略略點一點頭辈灼。他說,“讀過書巡莹,……我便考你一考甜紫。茴香豆的茴字骂远,怎樣寫的?”我想激才,討飯一樣的人,也配考我么贸营?便回過臉去,不再理會揣云”校孔乙己等了許久,很懇切的說道焚刚,“不能寫罷扇调?……我教給你,記著狼钮!這些字應(yīng)該記著熬芜。將來做掌柜的時候,寫賬要用涎拉。”我暗想我和掌柜的等級還很遠呢半火,而且我們掌柜也從不將茴香豆上賬季俩;又好笑,又不耐煩藐鹤,懶懶的答他道,“誰要你教娱节,不是草頭底下一個來回的回字么肄满?”孔乙己顯出極高興的樣子,將兩個指頭的長指甲敲著柜臺稠歉,點頭說,“對呀對呀带饱!……茴字有四樣寫法阅羹,你知道么?(留言回復(fù)你知道的茴字四種寫法

面試中會問到單例模式执庐,選擇其中一種或幾種寫法作為話頭导梆,考查設(shè)計模式和coding style的同時,還很容易擴展到其他問題递鹉。這里講解8種常用的寫法狡忙,下次遇到面試官可以直接甩到他面前址芯!但切忌生搬硬套,去記“茴香豆的寫法”北专。

簡介

單例模式是一種常用的軟件設(shè)計模式旬陡,其定義是單例對象的類只能允許一個實例存在。

實現(xiàn)思路

單例模式是一種常用的軟件設(shè)計模式驶睦,其定義是單例對象的類只能允許一個實例存在。單例模式要求類能夠有返回對象一個引用(永遠是同一個)和一個獲得該實例的方法(必須是靜態(tài)方法场航,通常使用getInstance這個名稱)溉痢。

8種寫法

1.餓漢式一

優(yōu)點:這種寫法比較簡單,靜態(tài)常量孩饼,就是在類裝載的時候就完成實例化。避免了線程同步問題立膛。

缺點:在類裝載的時候就完成實例化梯码,沒有達到Lazy Loading的效果。如果從始至終從未使用過這個實例鲁猩,則會造成內(nèi)存的浪費罢坝。

代碼:

public?class?Singleton {

//私有靜態(tài)常量

?? ?private?final?static?Singleton INSTANCE?=?new?Singleton();

//私有構(gòu)造

?? ?private?Singleton(){}

?//靜態(tài)工廠方法

?? ?public?static?Singleton getInstance(){

?? ??? ?return?INSTANCE;

?? ?}

}

2.餓漢式二

這種方式和上面的方式其實類似嘁酿,只不過將類實例化的過程放在了靜態(tài)代碼塊中,也是在類裝載的時候闹司,就執(zhí)行靜態(tài)代碼塊中的代碼,初始化類的實例牲迫。優(yōu)缺點和上面是一樣的借卧。

代碼:

public?class?Singleton {

?? ?private?static?Singleton instance;

?//靜態(tài)代碼塊

?? ?static?{

?? ??? ?instance?=?new?Singleton();

?? ?}

? ? ?//私有構(gòu)造

?? ?private?Singleton() {}

?? ?public?Singleton getInstance() {

?? ??? ?return?instance;

?? ?}

}

3.懶漢式一

這種寫法起到了Lazy Loading的效果铐刘,但是只能在單線程下使用。如果在多線程下,一個線程進入了if (singleton == null)判斷語句塊挂签,還未來得及往下執(zhí)行盼产,另一個線程也通過了這個判斷語句,這時便會產(chǎn)生多個實例啦辐。所以在多線程環(huán)境下不可使用這種方式蜈项。

代碼:

public?class?Singleton {

?? ?private?static?Singleton singleton;

//私有構(gòu)造

?? ?private?Singleton() {}

?? ?public?static?Singleton getInstance() {

?? ??? ?if?(singleton?==?null) {

?? ??? ??? ?singleton?=?new?Singleton();

?? ??? ?}

?? ??? ?return?singleton;

?? ?}

}

4.懶漢式二

解決上面第三種實現(xiàn)方式的線程不安全問題,做個線程同步就可以了侥衬,于是就對getInstance()方法進行了線程同步跑芳。缺點:效率太低了,每個線程在想獲得類的實例時候怀樟,執(zhí)行g(shù)etInstance()方法都要進行同步盆佣。而其實這個方法只執(zhí)行一次實例化代碼就夠了,后面的想獲得該類實例虑灰,直接return就行了痹兜。方法進行同步效率太低要改進。

代碼:

public?class?Singleton {

?? ?private?static?Singleton?singleton;

//私有構(gòu)造

?? ?private?Singleton() {}

?? ?public?static?synchronized?Singleton getInstance() {

?? ??? ?if?(singleton?==?null) {

?? ??? ??? ?singleton?=?new?Singleton();

?? ??? ?}

?? ??? ?return?singleton;

?? ?}

}

5.懶漢式三

由于第四種實現(xiàn)方式同步效率太低对湃,所以摒棄同步方法谐算,改為同步產(chǎn)生實例化的的代碼塊归露。但是這種同步并不能起到線程同步的作用。跟第3種實現(xiàn)方式遇到的情形一致恐锦,假如一個線程進入了if (singleton == null)判斷語句塊,還未來得及往下執(zhí)行陕贮,另一個線程也通過了這個判斷語句潘飘,這時便會產(chǎn)生多個實例。

代碼:

public?class?Singleton {

?? ?private?static?Singleton singleton;

//私有構(gòu)造

?? ?private?Singleton() {}

?? ?public?static?Singleton getInstance() {

?? ??? ?if?(singleton?==?null) {

?? ??? ??? ?synchronized?(Singleton.class) {

?? ??? ??? ?singleton?=?new?Singleton();

?? ??? ?}

?? ?}

?? ?return?singleton;

?? ?}

}

6.雙重檢查

Double-Check概念對于多線程開發(fā)者來說不會陌生戈擒,如代碼中所示艰毒,我們進行了兩次if (singleton == null)檢查丑瞧,這樣就可以保證線程安全了。這樣绊汹,實例化代碼只用執(zhí)行一次,后面再次訪問時诫欠,判斷if (singleton == null)浴栽,直接return實例化對象。優(yōu)點:線程安全被廓;延遲加載萝玷;效率較高。

代碼:

public?class?Singleton {

?? ?private?static?volatile?Singleton singleton;

//私有構(gòu)造

?? ?private?Singleton() {}

//?雙重檢查

?? ?public?static?Singleton getInstance() {

?? ??? ?if?(singleton?==?null) {

?? ??? ??? ?synchronized?(Singleton.class) {

//里面的判斷是一定要加的蜓斧,否則出現(xiàn)線程安全問題

?? ??? ??? ??? ?if?(singleton?==?null) {

?? ??? ??? ??? ??? ?singleton?=?new?Singleton();

?? ??? ??? ??? ?}

?? ??? ??? ?}

?? ??? ?}

?? ??? ?return?singleton;

?? ?}

}

7.靜態(tài)內(nèi)部類

這種方式跟餓漢式方式采用的機制類似睁冬,但又有不同。兩者都是采用了類裝載的機制來保證初始化實例時只有一個線程直奋。不同的地方在餓漢式方式是只要Singleton類被裝載就會實例化,沒有Lazy-Loading的作用搁胆,而靜態(tài)內(nèi)部類方式在Singleton類被裝載時并不會立即實例化邮绿,而是在需要實例化時,調(diào)用getInstance方法一死,才會裝載SingletonInstance類傻唾,從而完成Singleton的實例化。類的靜態(tài)屬性只會在第一次加載類的時候初始化伪煤,所以在這里凛辣,JVM幫助我們保證了線程的安全性,在類進行初始化時防泵,別的線程是無法進入的蝗敢。?

優(yōu)點:避免了線程不安全,延遲加載锁右,效率高讶泰。

代碼:

public?class?Singleton {

//私有構(gòu)造

?? ?private?Singleton() {}

//靜態(tài)內(nèi)部類

?? ?private?static?class?SingletonInstance {

?? ??? ?private?static?final?Singleton INSTANCE?=?new?Singleton();

?? ?}

?? ?public?static?Singleton getInstance() {

?? ??? ?return?SingletonInstance.INSTANCE;

?? ?}

}

8.枚舉

借助JDK1.5中添加的枚舉來實現(xiàn)單例模式痪署。不僅能避免多線程同步問題,而且還能防止反序列化重新創(chuàng)建新的對象余寥。可能是因為枚舉在JDK1.5中才添加劈狐,所以在實際項目開發(fā)中呐馆,很少見人這么寫過汹来。

代碼:

public?enum?Singleton {

?? ?INSTANCE;

?? ?public?void?whateverMethod() {

?? ?}

}

對比

對比
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末收班,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子社付,更是在濱河造成了極大的恐慌邻耕,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件啼辣,死亡現(xiàn)場離奇詭異御滩,居然都是意外死亡削解,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門舆声,熙熙樓的掌柜王于貴愁眉苦臉地迎上來柳爽,“玉大人,你說我怎么就攤上這事蛾找≌允模” “怎么了柿赊?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵碰声,是天一觀的道長熬甫。 經(jīng)常有香客問我,道長瞻颂,這世上最難降的妖魔是什么郑象? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任厂榛,我火速辦了婚禮,結(jié)果婚禮上击奶,老公的妹妹穿的比我還像新娘正歼。我一直安慰自己,他們只是感情好局义,可當我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布萄唇。 她就那樣靜靜地躺著檩帐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪另萤。 梳的紋絲不亂的頭發(fā)上湃密,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天,我揣著相機與錄音四敞,去河邊找鬼泛源。 笑死,一個胖子當著我的面吹牛忿危,可吹牛的內(nèi)容都是我干的达箍。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼铺厨,長吁一口氣:“原來是場噩夢啊……” “哼缎玫!你這毒婦竟也來了硬纤?” 一聲冷哼從身側(cè)響起赃磨,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤筝家,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后邻辉,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體溪王,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年恩沛,在試婚紗的時候發(fā)現(xiàn)自己被綠了在扰。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缕减。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡雷客,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出桥狡,到底是詐尸還是另有隱情搅裙,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布裹芝,位于F島的核電站部逮,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏嫂易。R本人自食惡果不足惜兄朋,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望怜械。 院中可真熱鬧颅和,春花似錦、人聲如沸缕允。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽障本。三九已至教届,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間驾霜,已是汗流浹背案训。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留粪糙,地道東北人强霎。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像猜旬,于是被迫代替她去往敵國和親脆栋。 傳聞我的和親對象是個殘疾皇子倦卖,可洞房花燭夜當晚...
    茶點故事閱讀 43,446評論 2 348