volatile修飾符
阿新 • • 發佈:2017-12-27
gpo 重排序 匯編 也不會 原子 產生 指令 觀察 pos
使用volatile修飾符修飾共享變量(類的成員變量或者類的靜態成員變量)會產生兩個效果:
1:保證了不同線程對這個變量操作的可見性,即:一個線程修改了這個變量的值,修改結果對其他線程是立即可見的;
2:禁止指令重排序;
使用volatile關鍵字,會強制性的將修改的值立即寫入主存;當線程2進行修改時,會導致線程1的工作內存中緩存變量stop緩存
行無效(反映到硬件層的話,就是cpu的L1或者L2緩存中對應的緩存行無效);由於線程1的工作內存中緩存變量的緩存行無效,
所以線程1再次讀取變量stop的值時,會去主存讀取。
下面這段話摘自《深入理解Java虛擬機》:
“觀察加入volatile關鍵字和沒有加入volatile關鍵字時所生成的匯編代碼發現,加入volatile關鍵字時,會多出一個lock前綴指令”
lock前綴指令實際上相當於一個內存屏障(也成內存柵欄),內存屏障會提供3個功能:
1)它確保指令重排序時不會把其後面的指令排到內存屏障之前的位置,也不會把前面的指令排到內存屏障的後面;即在執行到內存屏障這句指令時,在它前面的操作已經全部完成;
2)它會強制將對緩存的修改操作立即寫入主存;
3)如果是寫操作,它會導致其他CPU中對應的緩存行無效。
volatile不等同於synchronized,synchronized防止多個線程同時訪問同一段代碼,影響執行效率;volatile關鍵字無法保證原子性;
volatile修飾符