無論是中文的揮發性有機物還是英文的Volatile Organic Compounds均比較長,因此習慣上常用VOCs或者VOC來簡稱
問ArrayList、LinkedList的異同點,HashMap、TreeMap的區別)、併發(沒有問到JUC,單問synchronized/Lokc,消費者、生產者)、設計模式知道多少(單例、工廠全家桶、建造者、裝飾、策略、介面卡)、R
其實volatile還有一個保證,就是「每次使用前立即先從主記憶體重新整理最新的值」,執行緒t1修改完後,執行緒t2的變數副本會過期了,如圖:顯然,這裡還不是底層,實際上volatile保證可見性和禁止指令重排都跟「記憶體屏障」有關,我們編
為了提供一種比鎖更輕量級的執行緒之間通訊的機制,JSR-133專家組決定增強volatile的記憶體語義: 嚴格限制編譯器和處理器對volatile變數與普通變數的重排序,確保volatile的寫-讀與鎖的釋放-獲取具有相同的記憶體語義
非公平鎖獲取時,首先會用CAS更新volatile變數,這個操作同時具有volatile讀和寫的記憶體語義
讓我們設想這樣一個場景:作業系統在兩個不同的CPU核心上排程這些執行緒,其中:主執行緒在其核心快取中有ready和number變數的副本閱讀器執行緒也有它自己的快取副本主執行緒更新它自己快取的值在大多數現代處理器上,寫請求在發出之後不會立即
當兩個執行緒都要用到某一個變數且該變數的值會被改變時,應該用volatile宣告,該關鍵字的作用是防止最佳化編譯器把變數從記憶體裝入CPU暫存器中
【JMM記憶體模型8大原子操作】read讀取:從主記憶體中讀取資料load載入:將主記憶體讀取到的資料寫入工作記憶體use使用:從工作記憶體讀取出資料來計算assign賦值:將CPU計算出的值重新賦值到工作記憶體中store儲存:將工作記憶
而 synchronized 則可以保證變數的修改可見性和原子性
(2)修改volatile變數後會導致其他執行緒工作記憶體中對應的變數值失效
可見性即用volatile關鍵字修飾的成員變量表明該變數不存在工作執行緒的副本,執行緒每次直接都從主記憶體中讀取,每次讀取的都是最新的值,這也就保證了變數對其他執行緒的可見性
當要求使用 volatile 宣告的變數的值的時候,系統總是重新從它所在的記憶體讀取資料,即使它前面的指令剛剛從該處讀取過資料
對於複合操作,可以:同步塊技術(鎖)Java concurrent包(原子操作類等)總結volatile特點:透過使用Lock字首的指令禁止變數線上程工作記憶體中快取來保證volatile變數的記憶體可見性、透過插入記憶體屏障禁止會影響變數
這個例子中, 使用 volatile 不僅保證了變數的記憶體可見性,還禁止了指令的重排序,即保證了 volatile 修飾的變數編譯後的順序與程式的執行順序一樣
volatile定義:當對volatile變數執行寫操作後,JMM會把工作記憶體中的最新變數值強制重新整理到主記憶體寫操作會導致其他執行緒中的快取無效這樣,其他執行緒使用快取時,發現本地工作記憶體中此變數無效,便從主記憶體中獲取,這樣獲取到
同步塊的可見性是由“對一個變數執行unlock操作之前,必須先把此變數同步回主記憶體中(執行store和write操作)”這條規則獲得的,而final關鍵字的可見性是指:被final修飾的欄位是構造器一旦初始化完成,並且構造器沒有把“thi
首先是《深入理解Java虛擬機器(第三版)》:程式次序規則(Program Order Rule):在一個執行緒內,按照控制流順序,書寫在前面的操作先行發生於書寫在後面的操作