[Java記憶體模型]happens-before
重排序需要遵守happens-before規則,如果不符合,則編譯器和處理器不會對程式進行優化重排序
從JDK5開始,java使用新的JSR -133記憶體模型(本文除非特別說明,針對的都是JSR- 133記憶體模型)。JSR-133使用happens-before的概念來闡述操作之間的記憶體可見性。在JMM中,如果一個操作執行的結果需要對另一個操作可見,那麼這兩個操作之間必須要存在happens-before關係。這裡提到的兩個操作既可以是在一個執行緒之內,也可以是在不同執行緒之間。
與程式設計師密切相關的happens-before規則如下:
程式順序規則:一個執行緒中的每個操作,happens- before 於該執行緒中的任意後續操作。
監視器鎖規則:對一個監視器鎖的解鎖,happens- before 於隨後對這個監視器鎖的加鎖。
volatile變數規則:對一個volatile域的寫,happens- before 於任意後續對這個volatile域的讀。
傳遞性:如果A happens- before B,且B happens- before C,那麼A happens- before C。
注意,兩個操作之間具有happens-before關係,並不意味著前一個操作必須要在後一個操作之前執行!happens-before僅僅要求前一個操作(執行的結果)對後一個操作可見,且前一個操作按順序排在第二個操作之前(the first is visible to and ordered before the second)。happens- before的定義很微妙,後文會具體說明happens-before為什麼要這麼定義。
happens-before與JMM的關係如下圖所示:
如上圖所示,一個happens-before規則通常對應於多個編譯器和處理器重排序規則。對於java程式設計師來說,happens-before規則簡單易懂,它避免java程式設計師為了理解JMM提供的記憶體可見性保證而去學習複雜的重排序規則以及這些規則的具體實現。