volatile的記憶體語義 鎖的記憶體語義
一volatile的特性
可見性:對一個volatile變數的讀,總是能看到對這個volatile變數最後的寫入
原子性:對任意單個volatile變數的讀寫具有原子性,但類似於volatile++這種複合操作不具有原子性
二volatile寫讀建立的happens-before關係
從記憶體語義的角度來說,volatile的寫-讀與鎖的釋放-獲取有相同的記憶體效果:volatile寫與鎖的釋放有相同的記憶體語義,volatile讀與鎖的獲取有相同的記憶體語義
三volatile寫-讀的記憶體語義
volatile寫的記憶體語義:當寫一個volatile變數時,JMM會把該執行緒對應的本地記憶體中的共享變數值重新整理到主記憶體中
volatile讀的記憶體語義:當讀一個volatile變數時,JMM會把該執行緒對應的本地記憶體置為無效,執行緒接下來將從主記憶體中讀取共享變數
四volatile記憶體語義的實現
為了實現volatile記憶體語義,JMM會分別限制這兩種型別的重排序型別
對於x86處理器僅對寫-讀操作做重排序,JMM僅需在volatile寫後面插入一個StoreLoad屏障即可實現volatile寫-讀的記憶體語義
一鎖的釋放-獲取建立的happens-before關係
根據程式次序規則:1happens-before2,2happens-before3,4happens-before5,5happens-before6
根據監視器鎖規則:3happens-before4
根據happens-before的傳遞性:2happens-before5
二鎖的釋放和獲取的記憶體語義
當執行緒釋放鎖時,JMM會把該執行緒對應的本地記憶體中的共享變數重新整理到主記憶體中
當執行緒獲取鎖時,JMM會把該執行緒對應的本地記憶體置為無效
鎖釋放與volatile寫有相同的記憶體語義,鎖獲取與volatile讀有相同的記憶體語義
三鎖記憶體語義的實現
鎖記憶體語義的實現方式有兩種:
- 利用volatile變數的寫-讀所具有的記憶體語義
- 利用CAS所附帶的volatile讀和volatile寫的記憶體語義
reentrantlock分為公平鎖和非公平鎖,公平鎖和非公平鎖釋放時,最後都要寫一個volatile變數state,公平鎖獲取時,首先會去讀volatile變數,非公平鎖獲取時,首席前會用CAS更新volatile變數,這個操作同時具有volatile讀和volatile寫的記憶體語義