JAVA提供了volatile關鍵字,用於修飾變量。java
1.保證變量對全部線程的可見性
當一個線程修改了變量的值,會強制同步到內存,這樣其它線程可以當即讀取它的值。
2.禁止指令重排
經過插入內存屏障禁止CPU從新排序指令。緩存
volatile翻譯爲:不穩定的、易變的;
含義能夠理解爲:變量的值可能隨時會別的線程修改,保證其它線程能讀取到修改後的值。多線程
volatile能具有可見性、有序性,但不具有原子性。併發
適用場景:
線程循環標誌位變量;
單例模式中的實例變量;
讀多寫少,寫操做不依賴當前值。性能
JDK中應用:
ConcurrentHashMap的Entry的value和next被聲明爲volatile;
AtomicLong中的value被聲明爲volatile。線程
對比synchronized關鍵字:
volatile不具體原子性,所以不能保證多線程讀寫數據時數據的一致性;
但它不阻塞線程,性能高於synchronized。翻譯
當對非volatile變量進行讀寫的時候,每一個線程先從內存拷貝變量到CPU緩存;
若是計算機有多個CPU,每一個線程可能在不一樣的CPU上被處理,這意味着變量可能拷貝到不一樣的CPU緩存;排序
指線程之間的可見性,一個線程修改的狀態對另外一個線程是可見的。內存
指操做的最小單位,是不可分割的。
例:
原子性操做 a=0;
非原子性 a++;編譯器
指令是按順序串行執行的。 程序執行時按照代碼書寫的前後順序執行; 在Java內存模型中,容許編譯器和處理器對指令進行重排序; 重排序過程不會影響到單線程程序的執行,卻會影響到多線程併發執行的正確性。