Java多線程(十三)---重排序

移步java多線程系列文章
重排序是指編譯器處理器為了優(yōu)化程序性能而對(duì)指令序列進(jìn)行重新排序的一種手段重挑。

1 數(shù)據(jù)依賴性

  • 如果兩個(gè)操作訪問同一個(gè)變量囚似,且這兩個(gè)操作中有一個(gè)為寫操作,此時(shí)這兩個(gè)操作之間就存在數(shù)據(jù)依賴性顾画。
  • 數(shù)據(jù)依賴分為下列3種類型


    qq_pic_merged_1533562877559.jpg

    上面3種情況翎迁,只要重排序兩個(gè)操作的執(zhí)行順序,程序的執(zhí)行結(jié)果就會(huì)被改變叨咖。

  • 編譯器和處理器可能會(huì)對(duì)操作做重排序。
  • 編譯器和處理器在重排序時(shí),會(huì)遵守?cái)?shù)據(jù)依賴性甸各,編譯器和處理器不會(huì)改變存在數(shù)據(jù)依賴關(guān)系的兩個(gè)操作的執(zhí)行順序垛贤。
  • 這里所說的數(shù)據(jù)依賴性僅針對(duì)單個(gè)處理器中執(zhí)行的指令序列和單個(gè)線程中執(zhí)行的操作,不同處理器之間和不同線程之間的數(shù)據(jù)依賴性不被編譯器和處理器考慮趣倾。

2 as-if-serial語(yǔ)義

as-if-serial語(yǔ)義的意思是:不管怎么重排序(編譯器和處理器為了提高并行度)聘惦,(單線程)程序的執(zhí)行結(jié)果不能被改變。編譯器儒恋、runtime和處理器都必須遵守as-if-serial語(yǔ)義善绎。

  • 為了遵守as-if-serial語(yǔ)義,編譯器和處理器不會(huì)對(duì)存在數(shù)據(jù)依賴關(guān)系的操作做重排序诫尽,因?yàn)檫@種重排序會(huì)改變執(zhí)行結(jié)果禀酱。但是,如果操作之間不存在數(shù)據(jù)依賴關(guān)系牧嫉,這些操作就可能被編譯器和處理器重排序剂跟。
  • as-if-serial語(yǔ)義把單線程程序保護(hù)了起來(lái),遵守as-if-serial語(yǔ)義的編譯器酣藻、runtime和處理器共同為編寫單線程程序的程序員創(chuàng)建了一個(gè)幻覺:?jiǎn)尉€程程序是按程序的順序來(lái)執(zhí)行的浩聋。as-if-serial語(yǔ)義使單線程程序員無(wú)需擔(dān)心重排序會(huì)干擾他們,也無(wú)需擔(dān)心內(nèi)存可見性問題臊恋。

3 程序順序規(guī)則

示例--計(jì)算圓面積

double pi  = 3.14;           // A
double r   = 1.0;            // B
double area = pi * r * r;    // C

依賴關(guān)系如圖


qq_pic_merged_1533564066107.jpg
  • A和C之間存在數(shù)據(jù)依賴關(guān)系,同時(shí)B和C之間也存在數(shù)據(jù)依賴關(guān)系墓捻。因此在最終執(zhí)行的指令序列中抖仅,C不能被重排序到A和B的前面(C排到A和B的前面,程序的結(jié)果將會(huì)被改變)砖第。
  • 但A和B之間沒有數(shù)據(jù)依賴關(guān)系撤卢,編譯器和處理器可以重排序A和B之間的執(zhí)行順序。
qq_pic_merged_1533564176425.jpg
  • 如果A happens-before B梧兼,JMM并不要求A一定要在B之前執(zhí)行放吩。
  • JMM僅僅要求前一個(gè)操作(執(zhí)行的結(jié)果)對(duì)后一個(gè)操作可見,且前一個(gè)操作按順序排在第二個(gè)操作之前羽杰。
  • 這里操作A的執(zhí)行結(jié)果不需要對(duì)操作B可見渡紫;而且重排序操作A和操作B后的執(zhí)行結(jié)果,與操作A和操作B按happens-before順序執(zhí)行的結(jié)果一致考赛。在這種情況下惕澎,JMM會(huì)認(rèn)為這種重排序并不非法(not illegal),JMM允許這種重排序颜骤。

4 重排序?qū)Χ嗑€程的影響

示例

class ReorderExample {
       int a = 0;
       boolean flag = false;
       public void writer() {
           a = 1;                  // 1
           flag = true;            // 2
       }
       Public void reader() {
           if (f?lag) {            // 3
               int i =  a * a;     // 4
               ……
           }
       }
}

flag變量是個(gè)標(biāo)記唧喉,用來(lái)標(biāo)識(shí)變量a是否已被寫入。

  • 這里假設(shè)有兩個(gè)線程A和B,A首先執(zhí)行writer()方法八孝,隨后B線程接著執(zhí)行reader()方法董朝。線程B在執(zhí)行操作4時(shí),能否看到線程A在操作1對(duì)共享變量a的寫入呢干跛?

  • 答案是:不一定能看到子姜。

  • 由于操作1和操作2沒有數(shù)據(jù)依賴關(guān)系,編譯器和處理器可以對(duì)這兩個(gè)操作重排序驯鳖;

  • 同樣闲询,操作3和操作4沒有數(shù)據(jù)依賴關(guān)系,編譯器和處理器也可以對(duì)這兩個(gè)操作重排序浅辙。

  • 當(dāng)操作1和操作2重排序時(shí)

    qq_pic_merged_1533571255653.jpg

  • 程序執(zhí)行時(shí)扭弧,線程A首先寫標(biāo)記變量flag,隨后線程B讀這個(gè)變量记舆。由于條件判斷為真鸽捻,線程B將讀取變量a。此時(shí)泽腮,變量a還沒有被線程A寫入御蒲,在這里多線程程序的語(yǔ)義被重排序破壞了

  • 當(dāng)操作3和操作4重排序時(shí)

    qq_pic_merged_1533571526708.jpg

    操作3和操作4存在控制依賴關(guān)系诊赊。

  • 當(dāng)代碼中存在控制依賴性時(shí)厚满,會(huì)影響指令序列執(zhí)行的并行度。為此碧磅,編譯器和處理器會(huì)采用猜測(cè)(Speculation)執(zhí)行來(lái)克服控制相關(guān)性對(duì)并行度的影響碘箍。以處理器的猜測(cè)執(zhí)行為例,執(zhí)行線程B的處理器可以提前讀取并計(jì)算a*a鲸郊,然后把計(jì)算結(jié)果臨時(shí)保存到一個(gè)名為重排序緩沖(Reorder Buffer丰榴,ROB)的硬件緩存中。當(dāng)操作3的條件判斷為真時(shí)秆撮,就把該計(jì)算結(jié)果寫入變量i中四濒。猜測(cè)執(zhí)行實(shí)質(zhì)上對(duì)操作3和4做了重排序。重排序在這里破壞了多線程程序的語(yǔ)義职辨!

  • 在單線程程序中盗蟆,對(duì)存在控制依賴的操作重排序,不會(huì)改變執(zhí)行結(jié)果(這也是as-if-serial語(yǔ)義允許對(duì)存在控制依賴的操作做重排序的原因)舒裤;

  • 但在多線程程序中姆涩,對(duì)存在控制依賴的操作重排序,可能會(huì)改變程序的執(zhí)行結(jié)果惭每。

參考

《java并發(fā)編程的藝術(shù)》

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末骨饿,一起剝皮案震驚了整個(gè)濱河市亏栈,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌宏赘,老刑警劉巖绒北,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異察署,居然都是意外死亡闷游,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門贴汪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)脐往,“玉大人,你說我怎么就攤上這事扳埂∫挡荆” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵阳懂,是天一觀的道長(zhǎng)梅尤。 經(jīng)常有香客問我,道長(zhǎng)岩调,這世上最難降的妖魔是什么巷燥? 我笑而不...
    開封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮号枕,結(jié)果婚禮上缰揪,老公的妹妹穿的比我還像新娘。我一直安慰自己葱淳,他們只是感情好邀跃,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蛙紫,像睡著了一般换衬。 火紅的嫁衣襯著肌膚如雪捡需。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天疮方,我揣著相機(jī)與錄音喷斋,去河邊找鬼唁毒。 笑死,一個(gè)胖子當(dāng)著我的面吹牛星爪,可吹牛的內(nèi)容都是我干的浆西。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼顽腾,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼近零!你這毒婦竟也來(lái)了诺核?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤久信,失蹤者是張志新(化名)和其女友劉穎窖杀,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體裙士,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡入客,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了腿椎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片桌硫。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖啃炸,靈堂內(nèi)的尸體忽然破棺而出铆隘,到底是詐尸還是另有隱情,我是刑警寧澤肮帐,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布咖驮,位于F島的核電站,受9級(jí)特大地震影響训枢,放射性物質(zhì)發(fā)生泄漏托修。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一恒界、第九天 我趴在偏房一處隱蔽的房頂上張望睦刃。 院中可真熱鬧,春花似錦十酣、人聲如沸涩拙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)兴泥。三九已至,卻和暖如春虾宇,著一層夾襖步出監(jiān)牢的瞬間搓彻,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工嘱朽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留旭贬,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓搪泳,卻偏偏與公主長(zhǎng)得像稀轨,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子岸军,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

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

  • Java的并發(fā)采用的是共享內(nèi)存模型(而非消息傳遞模型)奋刽,線程之間共享程序的公共狀態(tài)瓦侮,線程之間通過寫-讀內(nèi)存中的公共...
    阿斯蒂芬2閱讀 471評(píng)論 0 1
  • 第2章 java并發(fā)機(jī)制的底層實(shí)現(xiàn)原理 Java中所使用的并發(fā)機(jī)制依賴于JVM的實(shí)現(xiàn)和CPU的指令。 2.1 vo...
    kennethan閱讀 1,392評(píng)論 0 2
  • 心性無(wú)染本清凈杨名,本自圓成不須觀脏榆;但離妄緣勤守護(hù),即如如佛本來(lái)面台谍。
    凈心_8cc7閱讀 189評(píng)論 0 0
  • 今天是周末须喂,我看天氣不錯(cuò),又去京城游玩趁蕊,事先做好交通規(guī)劃坞生,我就出發(fā)了。現(xiàn)在在京城也有一個(gè)半月了掷伙,我去了幾個(gè)地方是己,這...
    yellowriver00閱讀 343評(píng)論 0 0
  • 杞憂公子/文 1.辭骨 我喚名辭骨,是一個(gè)妖任柜。我和師父一直生活在落云山之上卒废,開始的幾百年間,師父從不讓我一人下山去...
    白寒露bhl閱讀 356評(píng)論 0 0