volatile關鍵字試圖阻止過度優化,volatile基本可以做到兩件事情:
1. 阻止編譯器爲了提高速度將一個變量緩存到寄存器內而不寫回。
2. 阻止編譯器調整操作 volatile變量的指令順序。
爲什麼要這麼做,這麼做有什麼目的?
我們先看2個例子,也是有關多線程安全的
例1:
x = 0
Thread1 Thread2
lock(); lock();
x++; x++;
unlock(); unlock();
表面上看,因爲有lock的保護,x的最終結果應該是2,這也是大部分執行的場景下的結果。但是,深入挖掘這個過程,其實並沒有那麼理想。編譯器爲了提高速度,把x放到某個寄存器裏,執行完x++後,有時候暫時不更新寄存器。導致結果可能爲1.
例2:
x = y = 0;
Thread1 Thread2
x = 1; y = 1;
r1 = y; r2 = x
表面上看,r1 和 r2至少應該有一個爲1,實際上r1 = r2 = 0的情況,會有發生。在執行程序的時候,由於cpu動態調度,爲了提高效率有可能會交換指令順序。同樣,編譯器在優化時候,也可能爲了效率而交換毫不相干的兩條相鄰指令。
導致執行時:
x = y = 0;
Thread1 Thread2
r1 = y; y = 1;
x = 1; r2 = x
注:volatile 可以完美解決例1的問題,但是volatile不能完全解決例2問題,只能阻止編譯器調整順序,無法阻止cpu動態調度換序。