volatile關鍵字 volatile是一個特殊的修飾符,只有成員變數才能使用它,與Synchronized及ReentrantLock等提供的互斥相比,Synchronized保證了Synchronized同步塊中變數的可見性,而volatile則是保證了所修飾變數的可見性。可見性指的是在一個線 ...
volatile關鍵字
volatile是一個特殊的修飾符,只有成員變數才能使用它,與Synchronized及ReentrantLock等提供的互斥相比,Synchronized保證了Synchronized同步塊中變數的可見性,而volatile則是保證了所修飾變數的可見性。可見性指的是在一個線程中修改變數的值以後,在其他線程中能夠看到這個值(在Java併發程式缺少同步類的情況下,多線程對成員變數的操作對其它線程是透明的(不可見))。因為volatile只是保證了同一個變數在多線程中的可見性,所以它更多是用於修飾作為開關狀態的變數。
java關鍵字volatile,從錶面意思上是說這個變數是易變的,不穩定的,事實上,確實如此,這個關鍵字的作用就是告訴編譯器,凡是被該關鍵字聲明的變數都是易變的、不穩定的。所以不要試圖對該變數使用緩存等優化機制,而應當每次都從它的記憶體地址中去讀值。使用volatile標記的變數在讀取或寫入時不需要使用鎖,這將減少產生死鎖的概率,使代碼保持簡潔。
請註意,這裡只是說每次讀取volatile的變數時都要從它的記憶體地址中讀取,並沒有說每次修改完volatile的變數後都要立刻將它的值寫回記憶體。也就是說volatile只提供了記憶體可見性,而沒有提供原子性,操作互斥提供了操作整體的原子性,同一個變數多個線程間的可見性與多個線程中操作互斥是兩件事情,所以說如果用這個關鍵字做高併發的安全機制的話是不可靠的。
volatile的用法如下:
public volatile static int count=0;//在聲明的時候帶上volatile關鍵字即可
什麼時候使用volatile關鍵字?當我們知道了volatile的作用,我們也就知道了它應該用在哪些地方,很顯然,最好是那種只有一個線程修改變數,多個線程讀取變數的地方。也就是對記憶體可見性要求高,而對原子性要求低的地方。
從上面的描述中,我們可以看出volatile與加鎖機制的主要區別是:加鎖機制既可以確保可見性又可以確保原子性,而volatile變數只有確保可見性。
原子操作Atomic
Volatile變數可以確保先行關係,保證下一個讀取操作會在前一個寫操作之後發生(即寫操作會發生在後續的讀操作之前),但它並不能保證原子性。例如用volatile修飾count變數,那麼count++ 操作就不是原子性的。
參考資料:
本文從概念上簡單描述了java併發中volatile關鍵字及原子操作atomic的部分內容,此處貼出一些優質文章以供讀者閱覽
(1)http://www.importnew.com/18126.html
(2)http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html