當一個變數定義為 volatile 之後,將具備兩種特性:
1.保證此變數的記憶體可見性。
2.禁止指令重排序優化。
以上
如果你想了解更多請往下讀
一、什麼事記憶體可見性呢?
我們都知道處理器有多個核,每個核都有cache,這樣每個核的cache就可能發生不同步的情況,一個核心對這個變數做了修改而另一個核心中因為cache的存在而不知道次變數已經修改。
volatile修飾的變數不允許執行緒(核)內部快取和重排序,即直接修改記憶體。所以對其他執行緒是可見的。宣告變數是 volatile 的,JVM 保證了每次讀變數都從記憶體中讀,跳過 CPU cache 這一步。
二、指令重排是啥?
是指CPU採用了允許將多條指令不按程式規定的順序分開傳送給各相應電路單元處理。
instance = new Instancce()
上面的程式碼雖然只有一行,但不是原子操作,它分成3步。
1.開闢記憶體空間
2.初始化物件
3.把初始化的物件指向記憶體地址上
複製程式碼
這3步的執行順序是不一定的,可能是132或123這樣。
如果是132這樣,在13之後程式意外終止,instance!=null,但是instance還沒初始化完成!
如果加了volatile關鍵字就禁止了指令重排。程式是123這樣執行,如果12或1執行了之後程式意外終止,instance還是null。