java併發-volatile關鍵字
阿新 • • 發佈:2019-06-14
說volatile的時候,必須先說一說,java的記憶體模型。
當一個執行緒操作共享變數時, 它首先從主記憶體複製共享變數到自己的工作記憶體 , 然後對工作記憶體裡的變數進行處理,處理完後將變數值更新到主記憶體。
上面只是一個抽象的概念,真實的情況如下圖。
執行緒1要使用共享變數count,從L1快取中取,發現沒有從L2快取中取,也沒有,接著從主記憶體中取。取到了值count=0,並把變數快取到兩級快取。
這時執行緒2修改count的值, 首先會從L1快取中取,發現沒有,從L2快取中取,快取命中。然後修改count=1,更新執行緒2的L1 Cache 和 L2 Cache,最後更新主記憶體中的值為1.
這時候執行緒1要修改count =1,獲取執行緒1裡的L1 cahce,取得count=0。明明執行緒2已經修改count為1,執行緒1獲取到的值確還是快取裡的值0。這 就是共享變數的記憶體不可見問題。
volatile就可以解決這個可見性的問題,可以猜想一下它是怎麼做到的?
對於volatile的變數,我不寫快取,直接寫到主記憶體,讀的時候,我直接從主記憶體讀取。
當 一個變數被宣告為 volatile 時,執行緒在寫入變數時不會把值快取在暫存器或者其他地方,而是會把值重新整理回主記憶體 。 當其他執行緒讀取該共享變數時 ,會從主記憶體重新獲取最新值,而不是使用當前執行緒的工作記憶體中的值。