int a = 10;
int c = a;
理論上來講每次使用a的時候都應該從a的地址來讀取變量值,但是這存在一個效率問題,就是每次使用a都要去內存中取變量值,然後再通過系統總線傳到CPU處理,這樣開銷會很大。所以那些編譯器優化者故作聰明,把a讀進CPU的cache裏,像上面的代碼,假如a在賦值期間沒有被改變,就直接從CPU的cache裏取a的副本來進行賦值。但是bug也顯而易見,可能a已經被另一個線程改變而重新寫回了內存,但這個線程並不知道,依舊按照原來的計劃從CPU的cache裏讀a的副本進來賦值給c,結果不幸發生了。於是編譯器的開發者爲了補救這一bug,提供了一個Volatile讓開發人員爲他們的過失埋單,或者說提供給開發人員了一個選擇效率的權利。當變量加上了Volatile時,編譯器就老老實實的每次都從內存中讀取這個變量值,否則就還按照優化的方案從cache裏讀。
- 當要訪問的變量已在synchronized代碼塊中,或者爲常量時,沒必要使用volatile;