volatile三大特性: 1. 內存可見性 2.不保證原子性 3. 禁止重排序
內存屏障的概念:
memory barrier是一個CPU指令。
指令邏輯:a.確保一些特定操做執行順序 b.影響一些數據的可見性
編譯器和CPU能夠在保證輸出結果同樣的狀況下對指令重排序,使性能獲得優化。
插入一個內存屏障,至關於告訴CPU和編譯器先於這個命令的必須先執行,後於這個命令的必須後執行。
內存屏障另外一個做用是強制更新一次不一樣CPU的緩存。例如:一個寫屏障會把這個屏障前寫入的數據刷新到緩存,
這樣任何試圖讀取該數據的線程將獲得最新值,而不用考慮究竟是被那個CPU核心或者那個CPU執行。
memory barrier和volatile的關係?上面的虛擬機指令裏面提到的,若是你的字段是volatile,java內存模型將在
寫操做後插入一個寫屏障指令,在讀操做前插入一個讀屏障指令。
若是對volatile字段進行讀寫操做,必須知道1.一旦寫完成,任何訪問這個字段的線程將會獲得最新的值
2.在寫入前,會保證全部以前發生的事已經發生,而且任何更新過的數據值也是可見的,由於內存屏障會把
以前的寫入值都刷新到緩存。java
樣例1緩存
class TestData{ //int count = 0; volatile int count = 0; public void Data(){ this.count = 10; } } public class VolatileTest { public static void main(String[] args){ TestData td = new TestData(); new Thread(()-> { System.out.println(Thread.currentThread().getName() + " " + td.count); try { TimeUnit.SECONDS.sleep(4); td.Data(); System.out.println(Thread.currentThread().getName() + " " + td.count); } catch (InterruptedException e) { e.printStackTrace(); } },"banana").start(); while (td.count == 0){ } System.out.println(Thread.currentThread().getName() + " " + td.count); } }