Java多線程系列——原子類的實現(CAS算法)

  Java提供的原子類是靠 sun 基於 CAS 實現的,CAS 是一種樂觀鎖。關於樂觀鎖與悲觀鎖html

  原子變量類至關於一種泛化的 volatile 變量,可以支持原子的和有條件的讀-改-寫操做。AtomicInteger 表示一個int類型的值,並提供了 get 和 set 方法,這些 Volatile 類型的int變量在讀取和寫入上有着相同的內存語義。它還提供了一個原子的 compareAndSet 方法(若是該方法成功執行,那麼將實現與讀取/寫入一個 volatile 變量相同的內存效果),以及原子的添加、遞增和遞減等方法。AtomicInteger 表面上很是像一個擴展的 Counter 類,但在發生競爭的狀況下能提供更高的可伸縮性,由於它直接利用了硬件對併發的支持。算法

AtomicInteger的實現


  AtomicInteger 是一個支持原子操做的 Integer 類,就是保證對 AtomicInteger 類型變量的增長和減小操做是原子性的,不會出現多個線程下的數據不一致問題。若是不使用 AtomicInteger,要實現一個按順序獲取的 ID,就必須在每次獲取時進行加鎖操做,以免出現併發時獲取到一樣的 ID 的現象。安全

  接下來經過源代碼來看 AtomicInteger 具體是如何實現的原子操做。併發

  首先看 value 的聲明:性能

private volatile int value;

  volatile 修飾的 value 變量,保證了變量的可見性。this

  incrementAndGet() 方法,下面是具體的代碼:spa

public final int incrementAndGet() {
        for (;;) {
            int current = get();
            int next = current + 1;
            if (compareAndSet(current, next))
                return next;
        }
 }

  經過源碼,能夠知道,這個方法的作法爲先獲取到當前的 value 屬性值,而後將 value 加 1,賦值給一個局部的 next 變量,然而,這兩步都是非線程安全的,可是內部有一個死循環,不斷去作 compareAndSet 操做,直到成功爲止,也就是修改的根本在 compareAndSet 方法裏面,compareAndSet()方法的代碼以下:線程

public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}

  compareAndSet()方法調用的compareAndSwapInt()方法的聲明以下,是一個native方法。 code

public final native boolean compareAndSwapInt(Object var1, long var2, int var4, intvar5);

  compareAndSet 傳入的爲執行方法時獲取到的 value 屬性值,next 爲加 1 後的值, compareAndSet 所作的爲調用 Sun 的 UnSafe 的 compareAndSwapInt 方法來完成,此方法爲 native 方法,compareAndSwapInt 基於的是 CPU 的 CAS 指令來實現的。因此基於 CAS 的操做可認爲是無阻塞的,一個線程的失敗或掛起不會引發其它線程也失敗或掛起。而且因爲 CAS 操做是 CPU 原語,因此性能比較好htm

  相似的,還有 decrementAndGet() 方法。它和 incrementAndGet() 的區別是將 value 減 1,賦值給next 變量。

      AtomicInteger 中還有 getAndIncrement() 和 getAndDecrement() 方法,他們的實現原理和上面的兩個方法徹底相同,區別是返回值不一樣,前兩個方法返回的是改變以後的值,即 next。而這兩個方法返回的是改變以前的值,即 current。還有不少的其餘方法,就不列舉了。

CAS算法

CAS(Compare-And-Swap)算法保證數據操做的原子性。

CAS 算法是硬件對於併發操做共享數據的支持。

CAS 包含了三個操做數:
  內存值 V
  預估值 A
  更新值 B

當且僅當 V == A 時,V 將被賦值爲 B,不然循環着不斷進行判斷 V 與 A 是否相等。

相關文章
相關標籤/搜索