高并發(fā)編程-04-線程安全-單例模式詳解

單例模式詳解

1勃蜘,編寫單例模式

餓漢式:不會存在線程安全的問題

public class Singleton1 {

????private Singleton1(){}

????private static Singleton1 singleton1 = new Singleton1();

????public static Singleton1 getInstance(){

????????return singleton1;

????}

}

懶漢式:會存在線程安全的問題,需要進行同步控制

以下的寫法存在線程安全闸英,經(jīng)過之前的學習,應(yīng)該很容易看出來吧

public class Singleton2 {

private Singleton2(){}

????private static Singleton2 singleton2;

????public static Singleton2 getInstance(){

????????if(singleton2 == null){

????????????singleton2 = new Singleton2();

????????}

????????return singleton2;

????}

}

驗證方式:

可以采用線程池的方式,創(chuàng)建多個線程去獲取實例對象纫谅,觀察獲取到的實例對象是否是同一個

2,解決懶漢式的線程安全問題

方法一:給方法加上synchronized即可

方法二:雙重檢測機制

public static Singleton2 getInstance(){

????if(singleton2 == null){

????????synchronized (Singleton2.class) {

????????????if(singleton2 == null){

????????????????singleton2 = new Singleton2();

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

????????}

? ? ?}

? ? ?return singleton2;

}

3.2 指令重拍的問題(要注意一個指令重拍的問題溅固,但是無法演示付秕,只能YY。侍郭。询吴。掠河。。猛计。)

上述的雙重檢測機制看似解決了線程安全的問題唠摹,但是有一個重要的概念-指令重排,指令重排是指實際執(zhí)行時有滑,JVM編譯器并非一定按照我們預(yù)想的順序去執(zhí)行跃闹,會對指令的執(zhí)行順序進行調(diào)整,這個時候就可能會出現(xiàn)線程不安全的情況

來毛好,我們好好分析下:

singleton2 = new Singleton2();

會被編譯器編譯成如下JVM指令:

memory= allocate();//1.分配對象的內(nèi)存空間

ctorinstance(memory);//2望艺。初始化對象

singleton2 = memory;//3.設(shè)置singleton2指向剛分配的內(nèi)存空間

如果這個時候,經(jīng)過指令重排后肌访,執(zhí)行順序為1,3,2 那么結(jié)果會如何找默?

假設(shè),線程A執(zhí)行了1,3后吼驶,線程B搶到了CPU資源惩激,此時線程B對于if的判斷結(jié)果會是false,

但是實際返回的是一個沒有完成初始化的對象蟹演。

4风钻,解決指令重排的問題-volatile

private volatile static Singleton2 singleton2;

使用volatile就可以解決這個問題,可以保證執(zhí)行的指令順序始終按照我們預(yù)想的1,2,3來走

我們一次性把單例說完吧酒请,接下來的實現(xiàn)方式跟多線程是沒有關(guān)系的

5骡技,靜態(tài)內(nèi)部類實現(xiàn)單例模式

使用classLoader的加載機制來實現(xiàn)懶加載

public class Singleton3 {

????private static class Lazy{

????????private static final Singleton3 SINGLETON3 = new Singleton3();

????}

????private Singleton3(){}

????public static Singleton3 getInstance(){

????????return Lazy.SINGLETON3;

????}

}

解釋下,兩個關(guān)鍵點:

1羞反,外部無法直接訪問靜態(tài)內(nèi)部類

2布朦,SINGLETON3對象的初始化時機并不是在單例類加載的時候,而是外界調(diào)用getInstance方法的時候

所以綜上所述昼窗,可以保證線程安全

6是趴,終極大招---反射怎么破?

上述講了這么多的方式澄惊,但是通過反射可以將私有的構(gòu)造方法設(shè)置為可訪問唆途,然后就可以創(chuàng)建很多不同的對象了

那怎么辦?

終極大招掸驱,通過枚舉

public enum SingletonEnum {

????INSTANCE;

}

有了枚舉窘哈,JVM會阻止反射獲取枚舉的私有構(gòu)造方法

唯一的缺點就是:枚舉是立即加載的模式

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市亭敢,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌图筹,老刑警劉巖帅刀,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件让腹,死亡現(xiàn)場離奇詭異,居然都是意外死亡扣溺,警方通過查閱死者的電腦和手機骇窍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來锥余,“玉大人腹纳,你說我怎么就攤上這事∏蹋” “怎么了嘲恍?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長雄驹。 經(jīng)常有香客問我佃牛,道長,這世上最難降的妖魔是什么医舆? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任俘侠,我火速辦了婚禮,結(jié)果婚禮上蔬将,老公的妹妹穿的比我還像新娘爷速。我一直安慰自己,他們只是感情好霞怀,可當我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布惫东。 她就那樣靜靜地躺著,像睡著了一般里烦。 火紅的嫁衣襯著肌膚如雪凿蒜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天胁黑,我揣著相機與錄音废封,去河邊找鬼。 笑死丧蘸,一個胖子當著我的面吹牛漂洋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播力喷,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼刽漂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了弟孟?” 一聲冷哼從身側(cè)響起贝咙,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎拂募,沒想到半個月后庭猩,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體窟她,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年蔼水,在試婚紗的時候發(fā)現(xiàn)自己被綠了震糖。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡趴腋,死狀恐怖吊说,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情优炬,我是刑警寧澤颁井,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站穿剖,受9級特大地震影響蚤蔓,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜糊余,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一秀又、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贬芥,春花似錦吐辙、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至威沫,卻和暖如春贤惯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背棒掠。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工孵构, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人烟很。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓颈墅,卻偏偏與公主長得像,于是被迫代替她去往敵國和親雾袱。 傳聞我的和親對象是個殘疾皇子恤筛,可洞房花燭夜當晚...
    茶點故事閱讀 43,527評論 2 349

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)芹橡,斷路器毒坛,智...
    卡卡羅2017閱讀 134,633評論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法林说,內(nèi)部類的語法粘驰,繼承相關(guān)的語法屡谐,異常的語法,線程的語...
    子非魚_t_閱讀 31,598評論 18 399
  • 前言 本文主要參考 那些年蝌数,我們一起寫過的“單例模式”。 何為單例模式度秘? 顧名思義顶伞,單例模式就是保證一個類僅有一個...
    tandeneck閱讀 2,490評論 1 8
  • 從三月份找實習到現(xiàn)在,面了一些公司剑梳,掛了不少唆貌,但最終還是拿到小米、百度垢乙、阿里锨咙、京東、新浪追逮、CVTE酪刀、樂視家的研發(fā)崗...
    時芥藍閱讀 42,213評論 11 349
  • 1 場景問題# 1.1 讀取配置文件的內(nèi)容## 考慮這樣一個應(yīng)用,讀取配置文件的內(nèi)容钮孵。 很多應(yīng)用項目骂倘,都有與應(yīng)用相...
    七寸知架構(gòu)閱讀 6,679評論 12 68