JMM之重排序

重排序是指編譯器和處理器為了優(yōu)化程序性能而對(duì)指令序列進(jìn)行重新排序的一種手段

  1. 在程序執(zhí)行時(shí),為了提高性能,編譯器和處理器通常會(huì)對(duì)指令進(jìn)行重排序,但是不能隨意的重排序,必須滿(mǎn)足一下兩點(diǎn)
  • 單線程情況下,不能改變程序執(zhí)行結(jié)果
  • 存在數(shù)據(jù)依賴(lài)性關(guān)系的操作之間不能重排序

數(shù)據(jù)的依賴(lài)性

  1. 如果兩個(gè)操作訪問(wèn)同一個(gè)共享變量,且這兩個(gè)操作有一個(gè)是寫(xiě)操作,那么這兩個(gè)操作之間就存在數(shù)據(jù)依賴(lài)性
  2. 編譯器和處理器會(huì)在重排序時(shí),遵守?cái)?shù)據(jù)依賴(lài)性,編譯器和處理器不會(huì)改變存在數(shù)據(jù)依賴(lài)性的兩個(gè)操作的執(zhí)行順序
  3. 這里的數(shù)據(jù)依賴(lài)性也只是針對(duì)單個(gè)處理器中執(zhí)行的指令序列和單個(gè)線程中執(zhí)行的操作,不同處理器之間和不同線程之間的數(shù)據(jù)依賴(lài)性不被編譯器和處理器考慮

as-if-serial語(yǔ)義

  1. as-if-serial語(yǔ)義的意思是,不管怎么重排序(編譯器和處理器為了提高并行度),單線程程序的執(zhí)行結(jié)果不能改變。編譯器、runtime和處理器都必須遵守as-if-serial語(yǔ)義
  2. 為了遵守as-if-serial語(yǔ)義,編譯器和處理器不會(huì)對(duì)存在數(shù)據(jù)依賴(lài)性的操作重排序,因?yàn)橐坏┲嘏判颍涂赡軙?huì)影響程序的執(zhí)行結(jié)果,對(duì)于不存在數(shù)據(jù)依賴(lài)性的操作,是可能會(huì)被編譯器和處理器做重排序處理
int a = 1; //A
int b = 2; //B
int c = a + b; //C
  1. 上面的數(shù)據(jù)依賴(lài)性關(guān)系是,C依賴(lài)于A和B,而A和B之間不存在數(shù)據(jù)依賴(lài)性,因此編譯器可以對(duì)A和B進(jìn)行重排序
  2. as-if-serial語(yǔ)義給我們一個(gè)錯(cuò)覺(jué),遵守as-if-serial語(yǔ)義的編譯器和處理器,在單線程的情況下,程序是按照順序執(zhí)行,其實(shí),對(duì)于不存在數(shù)據(jù)依賴(lài)性的操作,編譯器和處理器可以隨意的對(duì)其進(jìn)行重排序操作,以提高執(zhí)行效率

程序順序規(guī)則

  1. 根據(jù)happens-before的程序規(guī)則,上面的例子中
  • A happens-before B
  • B happens-before C
  • A happens-before C
  1. 這里的A happens-before C是根據(jù)happens-before的傳遞性推導(dǎo)出來(lái)的

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

  1. 如下代碼塊
class Example {
    int a = 0;
    boolean flag = false;
    public void writer() {
        a = 1;  //  1
        flag = true;  //  2
    }
    public void reader() {
        if (flaf) {  //  3
            int i = a + a;  //  4
        }
    }
}
  1. falg變量是一個(gè)標(biāo)記,用來(lái)標(biāo)記變量a是否已被寫(xiě)入,假如有線程A和線程B,A先執(zhí)行writer,B執(zhí)行reader,線程B在執(zhí)行操作4時(shí), 能否看到線程A在操作1對(duì)共享變量a的寫(xiě)入呢?答案是不一定能看到,由于1和2之間沒(méi)有數(shù)據(jù)依賴(lài)性,編譯器和處理器可以對(duì)這兩個(gè)操作進(jìn)行重排序,二3和4之間沒(méi)有數(shù)據(jù)依賴(lài)性,編譯器和處理器也可以對(duì)這兩個(gè)操作進(jìn)行重排序,當(dāng)1和2進(jìn)行重排序時(shí),線程B執(zhí)行的結(jié)果就處于一種待定的情況了

參考
周志明 《深入理解Java虛擬機(jī)》
方騰飛 《Java并發(fā)編程的藝術(shù)》

寫(xiě)在最后

我從未感覺(jué)如此強(qiáng)烈,我的靈魂離我如此遙遠(yuǎn),而且的存在卻如此的真實(shí)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容