并發(fā)三:同步原語final馍管、volatile的內(nèi)存語義

先介紹兩個(gè)概念this逃逸和內(nèi)存屏障

this逃逸
一個(gè)小栗子:

this逃逸示例

步驟1和步驟2之前沒有重排序的限制規(guī)定郭赐,因此這兩個(gè)操作是可以重排序的。如果出現(xiàn)了重排序那么執(zhí)行”read”方法的線程就有可能讀到final變量初始化之前的值,造成final變量未正確初始化确沸。

另外在構(gòu)造函數(shù)中注冊(cè)事件監(jiān)聽捌锭,在構(gòu)造函數(shù)中啟動(dòng)新線程都有可能會(huì)引發(fā)”this逃逸”。

在構(gòu)造函數(shù)返回之前罗捎,其他線程就持有了該對(duì)象的引用观谦,這種情況就叫this逃逸。調(diào)用尚未構(gòu)造完成的對(duì)象的方法可能引發(fā)錯(cuò)誤桨菜。

內(nèi)存屏障指

內(nèi)存屏障(memory barriers)也成為內(nèi)存柵欄豁状,是一組處理器指令捉偏,對(duì)內(nèi)存操作的順序進(jìn)行限制,大多數(shù)現(xiàn)代計(jì)算機(jī)為了提高性能而采取亂序執(zhí)行這使得內(nèi)存屏障成為必須泻红。JMM內(nèi)存語義底層是通過memory barriers實(shí)現(xiàn)的夭禽。

1、LoadLoad Barriers:示意指令"Load1; LoadLoad; Load2"谊路,保證Load1先讀取完畢讹躯,再執(zhí)行Load2及后續(xù)讀取指令。

2缠劝、StoreStore Barriers:示意指令"Store1; StoreStore; Store2"潮梯,保證Store1先刷新到內(nèi)存(對(duì)其他處理器可見),再執(zhí)行Store2及后續(xù)寫入操作惨恭。

3秉馏、LoadStore Barriers:示意指令"Load1; LoadStore; Store2",保證Load1先讀取完畢脱羡,再執(zhí)行Store2及后續(xù)寫入指令刷新到內(nèi)存萝究。

4、StoreLoad Barriers:示意指令"Store1; StoreLoad; Load2"锉罐,保證Store1先刷新到內(nèi)存(對(duì)其他處理器可見)糊肤,再執(zhí)行Load2及后續(xù)讀取指令。

在大多是處理器中氓鄙,會(huì)先執(zhí)行完屏障前的所有讀寫指令馆揉,再執(zhí)行屏障后的內(nèi)存訪問指令。

final語義

重排序

JMM對(duì)final的重排序做了特殊的規(guī)定抖拦,并且在JSR-133做了增強(qiáng)升酣,編譯器和處理器在對(duì)final域進(jìn)行重排序時(shí)候,都要遵循如下規(guī)則:

1态罪、在構(gòu)造函數(shù)內(nèi)對(duì)一個(gè)final域的寫入噩茄,與隨后把這個(gè)被構(gòu)造對(duì)象的引用賦值給一個(gè)引用變量,這兩個(gè)操作之間不能重排序复颈。

禁止編譯器重排序:編譯器不能將final域的寫操作重排序到構(gòu)造函數(shù)之外绩聘;

禁止處理器重排序:編譯器會(huì)在final與寫之后,構(gòu)造函數(shù)return之前插入個(gè)StoreStore屏障耗啦,用來禁止處理器將final域的寫操作重排序到構(gòu)造函數(shù)之外凿菩;

2、初次讀一個(gè)包含final域的對(duì)象的引用帜讲,與隨后初次讀這個(gè)final域衅谷,這兩個(gè)操作之間不能重排序。

讀對(duì)象引用似将,讀對(duì)象的final域 這兩個(gè)操作不能重排序获黔。

3蚀苛、在構(gòu)造函數(shù)內(nèi)對(duì)一個(gè)final引用的對(duì)象的成員域的寫入,與隨后在構(gòu)造函數(shù)外把這個(gè)被構(gòu)造對(duì)象的引用賦值給一個(gè)引用變量玷氏,這兩個(gè)操作之間不能重排序堵未。如下代碼s1處和s2禁止進(jìn)行重排序:

可見性

final修飾的變量作為不可變變量,只要對(duì)象是正確構(gòu)造的(沒有this逃逸發(fā)生)盏触,不需要任何同步措施就可以保證任何線程都能讀到變量在構(gòu)造函數(shù)中被初始化之后的值兴溜。

volatile語義

原子性

volatile是否保障原子性是個(gè)有爭(zhēng)議的話題,32位的JDK中volatile修飾后的long和double也具有原子性耻陕。但是volatile int i=0;i++;就不具備原子性,因此可以理解為對(duì)單次volatile變量的讀寫操作具有原子性刨沦,復(fù)合操作(如i++)不具有原子性诗宣。

重排序

為了實(shí)現(xiàn)volatile的語義,JMM限制了volatile的編譯器重排序和處理器重排序想诅,volatile變量編譯器重排序規(guī)則:

編譯器會(huì)在volatile寫操作前后插入StoreStore Barriers和StoreLoad Barriers召庞,volatile讀操作前后插入LoadLoad Barriers和LoadStore Barriers。通過插入內(nèi)存屏障來限制處理器對(duì)volatile進(jìn)行重排序来破。

volatile與可見性

通過volatile讀寫操作前后所插入的memory barriers就能夠看出篮灼,volatile變量能夠保證可見性。

小結(jié)

1徘禁、JMM保證final變量初始化時(shí)的有序性诅诱、禁止編譯器和處理器重排序。
2送朱、final作為不可變對(duì)象娘荡,正確初始化后(沒有this逃逸),能夠保障可見性驶沼。
3炮沐、volatile能夠保障單次操作的原子性
4、volatile能夠保障變量的可見性

并發(fā)專題目錄貼

碼字不易回怜,轉(zhuǎn)載請(qǐng)保留原文連接http://www.reibang.com/p/aa432a918db9

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末大年,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子玉雾,更是在濱河造成了極大的恐慌翔试,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,907評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件复旬,死亡現(xiàn)場(chǎng)離奇詭異遏餐,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)赢底,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門失都,熙熙樓的掌柜王于貴愁眉苦臉地迎上來柏蘑,“玉大人沮趣,你說我怎么就攤上這事慨默。” “怎么了吴攒?”我有些...
    開封第一講書人閱讀 164,298評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵庞溜,是天一觀的道長革半。 經(jīng)常有香客問我,道長流码,這世上最難降的妖魔是什么又官? 我笑而不...
    開封第一講書人閱讀 58,586評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮漫试,結(jié)果婚禮上六敬,老公的妹妹穿的比我還像新娘。我一直安慰自己驾荣,他們只是感情好外构,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著播掷,像睡著了一般审编。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上歧匈,一...
    開封第一講書人閱讀 51,488評(píng)論 1 302
  • 那天垒酬,我揣著相機(jī)與錄音,去河邊找鬼件炉。 笑死伤溉,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的妻率。 我是一名探鬼主播乱顾,決...
    沈念sama閱讀 40,275評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼宫静!你這毒婦竟也來了走净?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,176評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤孤里,失蹤者是張志新(化名)和其女友劉穎伏伯,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體捌袜,經(jīng)...
    沈念sama閱讀 45,619評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡说搅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了虏等。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片弄唧。...
    茶點(diǎn)故事閱讀 39,932評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡适肠,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出候引,到底是詐尸還是另有隱情侯养,我是刑警寧澤,帶...
    沈念sama閱讀 35,655評(píng)論 5 346
  • 正文 年R本政府宣布澄干,位于F島的核電站逛揩,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏麸俘。R本人自食惡果不足惜辩稽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望从媚。 院中可真熱鬧逞泄,春花似錦、人聲如沸静檬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拂檩。三九已至,卻和暖如春嘲碧,著一層夾襖步出監(jiān)牢的瞬間稻励,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評(píng)論 1 269
  • 我被黑心中介騙來泰國打工愈涩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留望抽,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,095評(píng)論 3 370
  • 正文 我出身青樓履婉,卻偏偏與公主長得像煤篙,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子毁腿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評(píng)論 2 354

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