volatile -- 最輕量級的同步機制
阿新 • • 發佈:2018-08-12
sig 變量 實現 屏障 賦值 一點 改變 開關 禁止
特性
- 保證變量對所有線程的可見性 -- 即當一條線程改變了該變量的值,其他線程立刻得知
- 禁止了指令重排序優化
Java內存模型實現volatile
load + use 必須連續一起出現,這就保證了線程從主內存讀到的值是最新的值
assign + store + write必須連續一起出現,這就保證了線程修改的值必須立刻更新到主內存
對於兩個變量A和B,如果先對A執行了use或assign操作,那麽就要比對B先執行read或write操作,這保證了指令不能重排序
並發不安全
雖然volatile變量的值一旦修改就能立刻得知,但是它的運算操作需要時間,在這段時間內變量的值可能被修改,因此不安全
如何保證線程安全?
只能用synchornized或者是Lock類實現同步
適用情況
- boolean flag情景,使用bool變量作為開關
- 雙鎖單例模式中使用volatile來保證實現唯一實例:如果沒有volatile,線程1new獲取實例的信息沒有立刻得到更新且放開了synchronized鎖,其他線程就會因為實例 == null繼續new
指令重排序
普通的變量只保證需要賦值的變量能得到正確結果而不保證指令執行順序
意義
JVM能夠根據處理器的特性(CPU的多級緩存系統、多核處理器等)適當的重新排序機器指令,使機器指令更符合CPU的執行特點,最大限度的發揮機器的性能
內存屏障
重排序時不能把後面的指令重排序到內存屏障之前,通過給指令加lock實現
性能
volatile總開銷比鎖低,只是寫操作因為插入了許多內存屏障可能會慢一點,如果volatile能滿足需求就用volatile
volatile -- 最輕量級的同步機制