volatile關鍵字html
volatile是一個特殊的修飾符,只有成員變量才能使用它,與Synchronized及ReentrantLock等提供的互斥相比,Synchronized保證了Synchronized同步塊中變量的可見性,而volatile則是保證了所修飾變量的可見性。可見性指的是在一個線程中修改變量的值之後,在其餘線程中可以看到這個值(在Java併發程序缺乏同步類的狀況下,多線程對成員變量的操做對其它線程是透明的(不可見))。由於volatile只是保證了同一個變量在多線程中的可見性,因此它更可能是用於修飾做爲開關狀態的變量。java
java關鍵字volatile,從表面意思上是說這個變量是易變的,不穩定的,事實上,確實如此,這個關鍵字的做用就是告訴編譯器,凡是被該關鍵字聲明的變量都是易變的、不穩定的。因此不要試圖對該變量使用緩存等優化機制,而應當每次都從它的內存地址中去讀值。使用volatile標記的變量在讀取或寫入時不須要使用鎖,這將減小產生死鎖的機率,使代碼保持簡潔。緩存
請注意,這裏只是說每次讀取volatile的變量時都要從它的內存地址中讀取,並無說每次修改完volatile的變量後都要馬上將它的值寫回內存。也就是說volatile只提供了內存可見性,而沒有提供原子性,操做互斥提供了操做總體的原子性,同一個變量多個線程間的可見性與多個線程中操做互斥是兩件事情,因此說若是用這個關鍵字作高併發的安全機制的話是不可靠的。安全
volatile的用法以下:多線程
public volatile static int count=0;//在聲明的時候帶上volatile關鍵字便可
何時使用volatile關鍵字?當咱們知道了volatile的做用,咱們也就知道了它應該用在哪些地方,很顯然,最好是那種只有一個線程修改變量,多個線程讀取變量的地方。也就是對內存可見性要求高,而對原子性要求低的地方。併發
從上面的描述中,咱們能夠看出volatile與加鎖機制的主要區別是:加鎖機制既能夠確保可見性又能夠確保原子性,而volatile變量只有確保可見性。高併發
Volatile變量能夠確保先行關係,保證下一個讀取操做會在前一個寫操做以後發生(即寫操做會發生在後續的讀操做以前),但它並不能保證原子性。例如用volatile修飾count變量,那麼count++ 操做就不是原子性的。優化
AtomicInteger是基於sun.misc.Unsafe來實現的,其定義以下:atom
該類中有以下一系列方法:spa
其中某些方法的實現以下:
此處再介紹一下AtomicReference,其定義以下:
該類使用了泛型,在定義該類型的變量時須要指定泛型實參,以下:
public
final
static
AtomicReference <String> ATOMIC_REFERENCE =
new
AtomicReference<String>(
"abc"
);
其中String即泛型實參
參考資料:
本文從概念上簡單描述了java併發中volatile關鍵字及原子操做atomic的部份內容,此處貼出一些優質文章以供讀者閱覽
(1)http://www.importnew.com/18126.html
(2)http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html
(3)http://www.importnew.com/20594.html