Volatile關鍵字
阿新 • • 發佈:2020-07-27
volatile關鍵字作為面試官最喜歡的問題之一肯定有著他獨一無二的作用,我想結合著面試題來幫助我更進一步理解volatile。
1.volatile如何保證可見性
我覺得主要是他的記憶體語義的緣故
volatile寫的記憶體語義是 更改執行緒volatile變數,執行緒會將這個volatile變數重新整理會主存。
volatile讀的記憶體語義是 執行緒讀volatile變數時,執行緒會將自己快取中的變數無效,然後從主存中讀取變數。
2.volatile記憶體語義是如何實現的
volatile為了限制編譯器重排序和處理器重排序在volatile的讀和寫前後都添加了記憶體屏障來防止volatile讀和寫前後的讀寫指令重排到volatile的後和前。
3.volatile能保證執行緒安全麼
volatile是不能保證執行緒安全的,volatile只是保證了可見性
例子就是 用volatile修飾一個數字,然後數字執行++ 或者 -- 操作,因為++ 和 -- 都不是原子操作,所以volatile是沒法保證執行緒安全的。
4.單例模式中的雙重檢查鎖的INSTACNE為什麼要用voliate修飾
首先是雙重檢查鎖
public class Singlen{ private Singlen(){ } private volatile static Instance instance;public Instance getInstance(){ if(instance == null){ synchronized(Singlen.class){ if(instance == null){ //error instance = new Instance(); } } } return instance; } }
其中程式碼error中的物件例項化可以分為三個指令
1.分配記憶體空間
2.初始化物件
3.物件指向記憶體空間
但是編譯器進行指令重排序的時候可能會將2.3指令進行重排序,雖然不會改變結果,但是當額外執行緒來判斷第一個檢查鎖的時候就會發現instance不為null,直接返回一個例項化不完全的物件。
所以使用volatile來封閉這個重排序,讓外界的讀操作只能在寫操作完成之後進行。
後續繼續補充!