從JDK5開(kāi)始,JAVA使用新的JSR -133內(nèi)存模型猛蔽,這個(gè)模型提出了happens-before的概念,通過(guò)這個(gè)概念來(lái)闡述操作之間的內(nèi)存可見(jiàn)性。它的簡(jiǎn)單定義是:如果一個(gè)操作執(zhí)行的結(jié)果需要對(duì)另一個(gè)操作可見(jiàn)小泉,那么這兩個(gè)操作之間必須存在happens-before關(guān)系。這里提到的兩個(gè)操作既可以是在一個(gè)線程之內(nèi)冕杠,也可以是在不同線程之間微姊。
與程序員密切相關(guān)的happens-before規(guī)則如下:
1)程序順序規(guī)則:一個(gè)線程中的每個(gè)操作,happens- before 于該線程中的任意后續(xù)操作
2)監(jiān)視器鎖規(guī)則:對(duì)一個(gè)監(jiān)視器鎖的解鎖分预,happens- before 于隨后對(duì)這個(gè)監(jiān)視器鎖的加鎖
3)volatile變量規(guī)則:對(duì)一個(gè)volatile域的寫(xiě)兢交,happens- before 于任意后續(xù)對(duì)這個(gè)volatile域的讀
4)傳遞性:如果A happens- before B,且B happens- before C笼痹,那么A happens- before C
兩個(gè)操作之間具有happens-before關(guān)系配喳,并不意味著前一個(gè)操作必須要在后一個(gè)操作之前執(zhí)行。happens-before僅僅要求前一個(gè)操作執(zhí)行的結(jié)果對(duì)后一個(gè)操作可見(jiàn)凳干,且前一個(gè)操作按順序排在第二個(gè)操作之前晴裹。
對(duì)于java程序員來(lái)說(shuō),happens-before規(guī)則簡(jiǎn)單易懂救赐,它避免java程序員為了理解JMM提供的內(nèi)存可見(jiàn)性保證而去學(xué)習(xí)復(fù)雜的重排序規(guī)則以及這些規(guī)則的具體實(shí)現(xiàn)方法涧团。
happens-before關(guān)系本質(zhì)上和as-if-serial語(yǔ)義是一回事。as-if-serial語(yǔ)義保證單線程內(nèi)程序的執(zhí)行結(jié)果不被改變净响,happens-before關(guān)系保證正確同步的多線程程序的執(zhí)行結(jié)果不被改變少欺。as-if-serial語(yǔ)義給編寫(xiě)單線程的程序員創(chuàng)造了一個(gè)幻境:?jiǎn)尉€程程序是按程序的順序來(lái)執(zhí)行的。happens-before關(guān)系給編寫(xiě)正確同步的多線程程序員創(chuàng)造了一個(gè)幻境:正確同步的多線程程序是按happens-before指定的順序來(lái)執(zhí)行的馋贤。
as-if-serial語(yǔ)義和happens-before這么做的目的赞别,都是為了在不改變程序執(zhí)行結(jié)果的前提下,盡可能的提高程序執(zhí)行的并行度配乓。