1. 程式人生 > >《Java程式猿面試筆試寶典》之volatile有什麼作用

《Java程式猿面試筆試寶典》之volatile有什麼作用

在由Java語言編寫的程式中。有時候為了提高程式的執行效率,編譯器會自己主動對其進行優化,把經常被訪問的變數快取起來,程式在讀取這個變數的時候有可能會直接從快取(比如暫存器)中來讀取這個值。而不會去記憶體中讀取。這樣做的一個優點是提高了程式的執行效率,但當遇到多執行緒程式設計時。變數的值可能由於別的執行緒而改變了,而該快取的值不會相應改變,從而造成應用程式讀取的值和實際的變數值不一致。比如,在本次執行緒內,當讀取一個變數時,為提高存取速度,會先把變數讀取到一個快取中,當以後再取變數值時,就直接從快取中取值。當變數值在本執行緒裡改變時,會同一時候把變數的新值複製到該快取中,以便保持一致。

       volatile是一個型別修飾符(typespecifier)。它是被設計用來修飾被不同執行緒訪問和改動的變數。被volatile型別定義的變數,系統每次用到它的時候都是直接從相應的記憶體其中提取,而不會利用快取。在使用了volatile修飾成員變數後,全部執行緒在不論什麼時候看到的變數的值都是同樣的。以下給出一個使用volatile的演示樣例。

public class MyThread  implements  Runnable {

       private volatile Boolean flag;

       public void stop() {

              flag = false;

       }

       public void run() {

              while(flag)

                     ;//do something

       }

}

       以上程式碼演示樣例是用來停止執行緒最經常使用的一種方法。假設boolean型別的變數flag沒有被宣告為volatile,那麼,當這個執行緒的run方法在推斷flag值的時候,使用的有可能是快取中的值,此時就不能及時地獲取其他執行緒對flag所做的操作,因此會導致執行緒不能及時地停止。

       須要注意的是,由於volatile不能保證操作的原子性,因此,普通情況下volatile不能取代sychronized。此外,使用volatile會阻止編譯器對程式碼的優化,因此會減少程式的執行效率。所以,除非迫不得已。否則。能不使用volatile。則儘量不要使用volatile。