在前面的文章裏面介紹了synchronized關鍵字的用法,這篇主要介紹volatile關鍵字的用法。緩存
Java語言提供了一種稍弱的同步機制,即volatile變量,用來確保將變量的更新操做通知到其它線程。當把變量聲明爲volatile類型後,編譯器與運行時都會注意到這個變量是共享的,所以不會將該變量上的操做與其它內存操做一塊兒重排序。Volatile變量不會被緩存在寄存器或者其它對處理器不可見的地方,所以在讀取volatile類型的變量時,總會返回最新寫入的值。多線程
volatile boolean asleep; while(!asleep){ //do something }
volatile變量一般用作某個操做完成、發生中斷或者狀態的標誌。雖然volatile變量使用很方便,可是存在一些侷限性:volatile的語義不足以確保遞增操做(count++)的原子性,除非你能確保只有一個線程對變量執行寫操做。spa
volatile與加鎖機制的主要區別是:加鎖機制既能夠確保可見性又能夠確保原子性,而volatile變量只有確保可見性。線程
下面以一個實例來講明使用volatile變量做爲狀態標誌在多線程裏面的使用。code
public class VolatileTest{ volatile boolean mFlag = false; public static void main(String[] args) { final VolatileTest mVolTest = new VolatileTest(); Thread t1 = new Thread(new Runnable() { public void run() { while(!mVolTest .mFlag ){ System.out.println("Working ..."); try { Thread.sleep(1000); } catch (InterruptedException ie) { // } } } }, "t1"); Thread t2 = new Thread( new Runnable() { public void run() { try { Thread.sleep(3000); //3秒後中止線程t1 mVolTest.mFlag = true; } catch (InterruptedException ie) { // } } }, "t2"); t1.start(); t2.start(); } }
當且僅當知足如下全部條件時,才應該使用volatile變量:blog
a)對變量的寫入操做不依賴變量的當前值,或者你能確保只有單個線程更新變量的值排序
b)該變量不會與其它狀態變量一塊兒歸入不變性條件中內存
c)在訪問變量時不須要加鎖編譯器