(Java 多線程系列)java volatile詳解

  在前面的文章裏面介紹了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)在訪問變量時不須要加鎖編譯器

相關文章
相關標籤/搜索