Java併發-volatile

volatile自身特性

可見性:對一個volatile變量的讀,總是能看到(任意線程)對這個volatile變量最後的寫入。
原子性:對任意單個volatile變量的讀/寫具有原子性,單類似於volatile++這種複合操作不具有原子性
這裏寫圖片描述
等同於
這裏寫圖片描述

volatile寫和鎖的釋放有相同的內存語義;volatile讀和鎖的獲取有相同的內存語義

volatile寫內存語義,鎖的釋放

當寫一個volatile變量時,JMM會把該線程對應的本地內存中的共享變量值刷新到主內存。
當線程獲取鎖時,JMM會把線程對應的本地內存置爲無效,然後臨界區的代碼從主存中讀入共享變量到工作內存。

volatile讀內存語義,鎖的獲取

當讀一個volatile變量時,JMM會把該線程對應的本地內存置爲無效。線程接下來從內存中讀取共享變量。並把本地內存中的值與主內存中的共享變量的值變爲一致。
當線程釋放鎖時,JMM會把該線程對應的本地內存中的共享變量刷新到主內存中。

這裏寫圖片描述

當第二個操作是volatile寫時,不管第一個操作是什麼,都不能重排序。這個規則確保volatile寫之前的操作不會被編譯器重排序到volatile寫之後。

編譯器在生成字節碼之前,會在指令序列中插入內存屏障,來禁止特定類型的處理器排序
這裏寫圖片描述

這裏寫圖片描述

volatile寫後面的StoreLoad屏障。這個屏障的作用是避免volatile寫與後面可能有的volatile讀/寫操作重排序。因爲編譯器常常無法準備判斷在一個volatile寫的後面是否需要插入一個StoreLoad屏障(可能一個volatile寫之後方法立即return)。JMM採取了保守策略:在每個volatile寫的後面,或者每個volatile讀的前面插入一個StoreLoad屏障。

在實際執行的過程中,會根據具體情況省略不必要的屏障。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章