AtomicInteger的併發處理

jdk5以後的java.util.concurrent.atomic包裏,多了一批原子處理類。主要用於在高併發環境下的高效程序處理。 html

這裏,咱們來看看AtomicInteger是如何使用非阻塞算法來實現併發控制的。 java

AtomicInteger的關鍵域只有一下3個: 算法

 

Java代碼   收藏代碼
  1. // setup to use Unsafe.compareAndSwapInt for updates  
  2. private static final Unsafe unsafe = Unsafe.getUnsafe();  
  3. private static final long valueOffset;  
  4. private volatile int value;  

 這裏, unsafe是java提供的得到對對象內存地址訪問的類,註釋已經清楚的寫出了,它的做用就是在更新操做時提供「比較並替換」的做用。實際上就是AtomicInteger中的一個工具。 數組

valueOffset是用來記錄value自己在內存的便宜地址的,這個記錄,也主要是爲了在更新操做在內存中找到value的位置,方便比較。 數據結構

注意:value是用來存儲整數的時間變量,這裏被聲明爲volatile,就是爲了保證在更新操做時,當前線程能夠拿到value最新的值(併發環境下,value可能已經被其餘線程更新了)。 併發

這裏,咱們以自增的代碼爲例,能夠看到這個併發控制的核心算法: 高併發

 

 J2SE 5.0提供了一組atomic class來處理更加複雜的狀況。相對於只能處理單一的atomic操做,這些class可以讓多個操做被atomic地對待,這樣咱們也就有可能不須要同步就能實現同步機制所作到的一切。
      咱們能夠用AtomicInteger,AtomicLong,AtomicBoolean和AtomicReference這四個class實現的四個基本的atomic類型來處理integer,long,boolean和對象。這些class都提供了兩個構造器:默認的構造器的值爲0,false,false或者null,另外一個構造器是以程序設計者所指定的值來初始化和建立變量。set()和get()這兩個方法就提供了volatile變量所具備的的功能:可以atomic的設定與取得值,由於它們可以確保數據的讀寫是從主存儲器上運行的。可是這些class還提供了更多的操做來適應volatile沒法解決的狀況。
      getAndSet()可以在返回初始值的時候atomic的設定變量成新值,徹底不須要任何的同步lock。compareAndSet()與weakCompareAndSet()是有條件的修改程序的方法,這兩個方法都要取用兩個參數:在方法啓動時預期數據所具備的的值,以及要把數據所設定成的值。它們都只會在變量具備預期值的時候纔會設定成新值,若是當前值不等於預期值,該變量就不會被從新賦值而且返回false。這兩個方法之間有什麼區別嗎?第二個方法少了一項保證:若是方法返回的值false,該變量不會被變更,可是這並不表示現有值不是預期值,也就是說,這個方法無論初始值是不是預期值均可能會沒法更新改值。
      incrementAndGet(),decrementAndGet(),getAndIncrement()和getAndDecrement()提供了前置遞增,前置遞減,後遞增和後遞減,之因此有這些方法,是由於這些操做都不是atomic的。
      addAndGet()和getAndAdd()提供了"前置"和"後置"的運算符給指定值的加法運算,它們可以讓程序對變量增或者減一個指定值,包括了負值,因此咱們就不須要一個相對的減法運算。
      atomic package目前沒有實現atomic字符或者浮點變量,可是咱們能夠使用AtomicInteger來處理字符,就像是字符常量同樣,可是使用atomic的浮點數須要atomic帶有隻讀浮點數值的受管理對象。咱們也沒有實現atomic數組,並無功能可以對整個數組作atomic化的變更,最多就是經過使用AtomicInteger,AtomicLong和AtomicReference的數組來模型化,可是數組的大小必須在構造時就指定好,而且在操做過程當中必須提供索引。至於Boolean的atomic數組,一樣也能夠經過AtomicInteger來實現。
     atomic package還有兩個類:AtomicMarkableReference和AtomicStampedReterence。這兩個類可以讓mark或stamp跟在任何對象的引用上,更精確點講,AtomicMarkableReference提供了一種包括對象引用結合boolean的數據結構,而AtomicStampedReference提供了一種包括對象引用結合integer的數據結構。
     其實,atomic class的這些方法在本質上是同樣的。在使用的時候,get()方法須要咱們傳入一個數組做爲參數,stamp或者mark被存儲在數組的第一個元素而引用被正常返回。其餘的get()方法就只是返回引用,mark或者stamp。
    set()與compareAndSet()方法須要額外的參數來表明mark或者stamp。最後,這些class都帶有attemptMark()或attemptStamp()方法,用來依據期待的引用設定mark或者stamp。


http://www.cnblogs.com/wenjiang/p/3276433.html
相關文章
相關標籤/搜索