單例模式中的volatile關(guān)鍵字

在之前學(xué)習(xí)了單例模式在多線程下的設(shè)計(jì)恢恼,疑惑為何要加volatile關(guān)鍵字民傻。加與不加有什么區(qū)別呢?這里我們就來(lái)研究一下。單例模式的設(shè)計(jì)可以參考個(gè)人總結(jié)的這篇文章

??背景:在早期的JVM中漓踢,synchronized存在巨大的性能開(kāi)銷牵署。因此,有人想出了一個(gè)“聰明”的技巧:雙重檢查鎖定(Double-Checked Locking)喧半。人們想通過(guò)雙重檢查鎖定來(lái)降低同步的開(kāi)銷奴迅。下面是使用雙重檢查鎖定來(lái)實(shí)現(xiàn)延遲初始化的示例代碼。

public class DoubleCheckedLocking { // 1
    private static Instance instance; // 2
    public static Instance getInstance() { // 3
        if (instance == null) { // 4:第一次檢查
            synchronized (DoubleCheckedLocking.class) { // 5:加鎖
                if (instance == null) // 6:第二次檢查
                instance = new Instance(); // 7:問(wèn)題的根源出在這里
            } // 8
        } // 9
        return instance; // 10
    } // 11
}

上述的Instance類變量是沒(méi)有用volatile關(guān)鍵字修飾的薯酝,會(huì)導(dǎo)致這樣一個(gè)問(wèn)題:
在線程執(zhí)行到第4行的時(shí)候半沽,代碼讀取到instance不為null時(shí),instance引用的對(duì)象有可能還沒(méi)有完成初始化吴菠。
主要的原因是重排序者填。重排序是指編譯器和處理器為了優(yōu)化程序性能而對(duì)指令序列進(jìn)行重新排序的一種手段。
第7行的代碼創(chuàng)建了一個(gè)對(duì)象做葵,這一行代碼可以分解成3個(gè)操作:

memory = allocate();  // 1:分配對(duì)象的內(nèi)存空間
ctorInstance(memory); // 2:初始化對(duì)象
instance = memory;  // 3:設(shè)置instance指向剛分配的內(nèi)存地址

根源在于代碼中的2和3之間占哟,可能會(huì)被重排序。例如:

memory = allocate();  // 1:分配對(duì)象的內(nèi)存空間
instance = memory;  // 3:設(shè)置instance指向剛分配的內(nèi)存地址
// 注意酿矢,此時(shí)對(duì)象還沒(méi)有被初始化榨乎!
ctorInstance(memory); // 2:初始化對(duì)象

這在單線程環(huán)境下是沒(méi)有問(wèn)題的,但在多線程環(huán)境下會(huì)出現(xiàn)問(wèn)題:

image

B線程會(huì)看到一個(gè)還沒(méi)有被初始化的對(duì)象瘫筐。
image

A2和A3的重排序不影響線程A的最終結(jié)果蜜暑,但會(huì)導(dǎo)致線程B在B1處判斷出instance不為空,線程B接下來(lái)將訪問(wèn)instance引用的對(duì)象策肝。此時(shí)肛捍,線程B將會(huì)訪問(wèn)到一個(gè)還未初始化的對(duì)象。
所以只需要做一點(diǎn)小的修改(把instance聲明為volatile型)之众,就可以實(shí)現(xiàn)線程安全的延遲初始化拙毫。因?yàn)楸籿olatile關(guān)鍵字修飾的變量是被禁止重排序的。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末棺禾,一起剝皮案震驚了整個(gè)濱河市缀蹄,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌膘婶,老刑警劉巖缺前,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異竣付,居然都是意外死亡诡延,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門古胆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)肆良,“玉大人筛璧,你說(shuō)我怎么就攤上這事∪鞘眩” “怎么了夭谤?”我有些...
    開(kāi)封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)巫糙。 經(jīng)常有香客問(wèn)我朗儒,道長(zhǎng),這世上最難降的妖魔是什么参淹? 我笑而不...
    開(kāi)封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任醉锄,我火速辦了婚禮,結(jié)果婚禮上浙值,老公的妹妹穿的比我還像新娘恳不。我一直安慰自己,他們只是感情好开呐,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布烟勋。 她就那樣靜靜地躺著,像睡著了一般筐付。 火紅的嫁衣襯著肌膚如雪卵惦。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天瓦戚,我揣著相機(jī)與錄音沮尿,去河邊找鬼。 笑死较解,一個(gè)胖子當(dāng)著我的面吹牛蛹找,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播哨坪,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼乍楚!你這毒婦竟也來(lái)了当编?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤徒溪,失蹤者是張志新(化名)和其女友劉穎忿偷,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體臊泌,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鲤桥,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了渠概。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片茶凳。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡嫂拴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出贮喧,到底是詐尸還是另有隱情筒狠,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布箱沦,位于F島的核電站辩恼,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏谓形。R本人自食惡果不足惜灶伊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望寒跳。 院中可真熱鬧聘萨,春花似錦、人聲如沸冯袍。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)康愤。三九已至儡循,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間征冷,已是汗流浹背择膝。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留检激,地道東北人肴捉。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像叔收,于是被迫代替她去往敵國(guó)和親齿穗。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

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

  • 在分析完企業(yè)經(jīng)營(yíng)成果和經(jīng)營(yíng)的本質(zhì)之后饺律,德魯克接著介紹了幾種重要的競(jìng)爭(zhēng)戰(zhàn)略窃页。前面已經(jīng)介紹了一種戰(zhàn)略:發(fā)揮企業(yè)的優(yōu)勢(shì)。...
    翁華安閱讀 881評(píng)論 0 0
  • 從畢業(yè)到現(xiàn)在复濒,工作已經(jīng)有三到四年了脖卖。這幾年,在工作中積累了不少的知識(shí)和經(jīng)驗(yàn)巧颈,但都是自己一個(gè)人默默無(wú)聞的做畦木。 每次逛...
    esonyf閱讀 166評(píng)論 0 0
  • 11月23日,白老師砸泛,燕子和我十籍,我們?nèi)艘黄鹑ヱ雎?tīng)了新教材培訓(xùn)報(bào)告蛆封,聽(tīng)了專家的報(bào)告,頓覺(jué)有了明確的指明燈妓雾,初步明白...
  • 河流之地的形勢(shì)與戰(zhàn)略 著有《地理與世界霸權(quán)》的地緣政治學(xué)者菲爾格里夫(James Fairgrieve)將中...
    座客蒼涼閱讀 1,105評(píng)論 0 3