天天看點

JMM——volatile與記憶體屏障

為了實作volatile記憶體語義,JMM會分别限制編譯器重排序和處理器重排序

JMM——volatile與記憶體屏障

1.當第一個操作為普通的讀或寫時,如果第二個操作為volatile寫,則編譯器不能重排序這兩個操作(1,3)

2.當第一個操作是volatile讀時,不管第二個操作是什麼,都不能重排序。這個規則確定volatile讀之後的操作不會被編譯器重排序到volatile讀之前(第二行)

3.當第一個操作是volatile寫,第二個操作是volatile讀時,不能重排序(3,2)

4.當第二個操作是volatile寫時,不管第一個操作是什麼,都不能重排序(第三列)

為了實作volatile的記憶體語義,編譯器在生成位元組碼時,會在指令序列中插入記憶體屏障來禁止特定類型的處理器重排序。

JMM基于保守政策的JMM記憶體屏障插入政策:

1.在每個volatile寫操作的前面插入一個StoreStore屏障

2.在每個volatile寫操作的後面插入一個SotreLoad屏障

3.在每個volatile讀操作的後面插入一個LoadLoad屏障

4.在每個volatile讀操作的後面插入一個LoadStore屏障

JMM——volatile與記憶體屏障

上圖的StoreStore屏障可以保證在volatile寫之前,其前面的所有普通寫操作已經對任意處理器可見了

因為StoreStore屏障将保障上面所有的普通寫在volatile寫之前重新整理到主記憶體

JMM——volatile與記憶體屏障
JMM——volatile與記憶體屏障

x86處理器僅僅會對寫-讀操作做重排序

是以會省略掉讀-讀、讀-寫和寫-寫操作做重排序的記憶體屏障

在x86中,JMM僅需在volatile後面插入一個StoreLoad屏障即可正确實作volatile寫-讀的記憶體語義

這意味着在x86處理器中,volatile寫的開銷比volatile讀的大,因為StoreLoad屏障開銷比較大

JMM——volatile與記憶體屏障
JMM——volatile與記憶體屏障