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變量只有確保可見性。
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