詳細解析Java內存湖饱,處理器重排序掖蛤,編譯器重排序以及它對線程的影響

????歡迎大家搜索“小猴子的技術筆記”關注我的公眾號,有問題可以及時和我交流井厌。

????我們在編寫程序的時候有一個編寫代碼的順序坠七,那么計算機執(zhí)行的時候就是按照我們編寫代碼的順序來執(zhí)行的嗎?答案是:不一定旗笔。如果兩個代碼之間沒有依賴關系的話彪置,那么編譯器和處理器常常會對我們的編碼指令重排序。重排序是指編譯器和處理器為了優(yōu)化程序性能而對指令序列進行重新排序的一種手段蝇恶,我們編寫一個Java代碼從源代碼到最后的執(zhí)行順序如下:


在這里插入圖片描述

????源代碼:也就是我們用開發(fā)工具寫的代碼拳魁。

????編譯器優(yōu)化重排序:編譯器在不改變單線程程序語義的前提下,可以重新安排語句的執(zhí)行順序撮弧。

????指令級并行重排序:現(xiàn)代處理器采用了指令級并行技術來將多條指令重疊執(zhí)行潘懊。如果數(shù)據(jù)不存在依賴,處理器就可以改變語句對應機器指令的執(zhí)行順序贿衍。

????內存系統(tǒng)重排序:當代處理器使用寫緩沖區(qū)來臨時保存向內存寫入的數(shù)據(jù)授舟,這使得加載和存儲操作看上去可能是在亂序執(zhí)行。我們來看下面這個例子:

????假設有處理器A和處理器B兩個處理器贸辈,a和b的初始化狀態(tài)為0 释树。在處理器A中執(zhí)行下面代碼(均為偽代碼):

a=1;
x=b;

????在處理器B中執(zhí)行下面代碼:


b=2;
y=a;

????處理器允許執(zhí)行后得到的結果是x=y=0。來看一下處理器和內存的交互圖:


在這里插入圖片描述

????因為現(xiàn)代處理器都會使用寫緩存,因此現(xiàn)在處理器都會允許對寫-讀的操作進行重排序奢啥。

????寫緩沖區(qū)的作用:因為處理器和內存的處理速度不是一個量級的秸仙,因此避免由于處理器停頓下來向內存寫入數(shù)據(jù)而產生延遲,所以每個處理器都有一個僅僅對自己處理器可見的寫緩沖區(qū)∽ぃ現(xiàn)代處理器會通過批處理的方式刷新寫緩沖區(qū)寂纪,以及合并寫緩沖區(qū)中對同一個內存地址的多次寫,減少對數(shù)據(jù)總線的調用赌结。

????介紹完了重排序之后捞蛋,我們需要知道在單核處理器中,如果兩個變量存在了數(shù)據(jù)依賴柬姚,編譯器和處理器是不會改變存在數(shù)據(jù)依賴關系的兩個操作的執(zhí)行順序的拟杉。那么重排序對多線程有什么影響呢?來看看下面的這個例子:


public class ReorderExample {
    int a = 0;
    boolean flag = false;
    public void writer() {
        // 操作1
        a = 1;
        // 操作2
        flag = true;
    }
    public void reader() {
        // 操作3
        if (flag) {
            // 操作4
            int i = a * a;
            System.out.println(i);
        }
    }
}

????如果A線程先執(zhí)行“writer()”方法伤靠,B線程接著執(zhí)行“reader()”方法捣域,那么線程B在執(zhí)行的時候能否看到線程A對共享變量a的寫入呢?

????答案是不一定能看到宴合,因為操作1和操作2沒有數(shù)據(jù)依賴關系焕梅,所以編譯器和處理器可以對這兩個操作進行重排序。假定操作1和操作2進行了重排序卦洽,那么線程B在執(zhí)行的時候得到的結果就有可能是i=0贞言。

????在操作3和操作4先進行了一個判斷在計算,它們之間存在控制依賴關系阀蒂。當代碼中存在控制依賴性時该窗,會影響指令序列執(zhí)行的并行度。線程B處理器可以提前讀取并計算“a*a”蚤霞,然后把計算結果臨時保存到一個名為重排序緩存(Reorder Buffer酗失,ROB)的硬件緩存中。當操作3的條件判斷為真的時候昧绣,就把該計算結果寫入到變量i中规肴。


在這里插入圖片描述

????由此可以明白,如果多線程的話夜畴,重排序是會影響多線程的執(zhí)行結果的

????歡迎大家搜索“小猴子的技術筆記”關注我的公眾號拖刃,有問題可以及時和我交流。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末贪绘,一起剝皮案震驚了整個濱河市兑牡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌税灌,老刑警劉巖均函,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件亿虽,死亡現(xiàn)場離奇詭異,居然都是意外死亡边酒,警方通過查閱死者的電腦和手機经柴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門狸窘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來墩朦,“玉大人,你說我怎么就攤上這事翻擒∶セ粒” “怎么了?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵陋气,是天一觀的道長劳吠。 經常有香客問我,道長巩趁,這世上最難降的妖魔是什么痒玩? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮议慰,結果婚禮上蠢古,老公的妹妹穿的比我還像新娘。我一直安慰自己别凹,他們只是感情好草讶,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著炉菲,像睡著了一般堕战。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上拍霜,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天嘱丢,我揣著相機與錄音,去河邊找鬼祠饺。 笑死越驻,一個胖子當著我的面吹牛,可吹牛的內容都是我干的吠裆。 我是一名探鬼主播伐谈,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼试疙!你這毒婦竟也來了诵棵?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤祝旷,失蹤者是張志新(化名)和其女友劉穎履澳,沒想到半個月后嘶窄,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡距贷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年柄冲,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片忠蝗。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡现横,死狀恐怖,靈堂內的尸體忽然破棺而出阁最,到底是詐尸還是另有隱情戒祠,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布速种,位于F島的核電站姜盈,受9級特大地震影響,放射性物質發(fā)生泄漏配阵。R本人自食惡果不足惜馏颂,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望棋傍。 院中可真熱鬧救拉,春花似錦、人聲如沸舍沙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拂铡。三九已至壹无,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間感帅,已是汗流浹背斗锭。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留失球,地道東北人岖是。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像实苞,于是被迫代替她去往敵國和親豺撑。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內容