1. 程式人生 > >併發(2) 原子類

併發(2) 原子類

  java併發包中提供了一些原子變數類,這些原子變數類提供的方法本身就是一個原子操作。

例如

public class CountingFactorizer implements Servlet{

          private final AtomicLong count = new AtomicLong(0);

          public void service(ServletRequest req,ServletResponse resp){

                    count.incrementAndGet();

          }

}

  上例實現了對訪問的計數,這是一個執行緒安全的類,因為它的計算是一個原子操作。java併發包中還提供了各種型別的原子變數類。

  那麼原子變數類是如何實現計算的原子性的呢?

public final int incrementAndGet() {

 for (;;) {

  int current = get();

  int next = current + 1;

   if (compareAndSet(current, next))

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

  上面的方法中,首現獲取了當前的值,然後對當前值進行加1操作,然後通過unsafe的compareAndSet方法來設定改值。

  unsafe的compareAndSet方法做了什麼呢?他首先會去比較當前值是不是預期的值,如果不是返回false,如果是設定新值並返回true。

  這種方式也叫做CAS,他不僅是原子類的底層實現方式,也是java鎖的底層實現方式。就是在設定新值之前判斷當前是否還是老值,如果是則設定新值,如果不是則重新計算新值後再嘗試設定。當人CAS實現原子性的基礎是compareAndSet本身是一個原子操作

原子類

原子類 說明
AtomicBoolean boolean原子類 
AtomicInteger int原子類
AtomicLong long原子類
AtomicReference 引用原子類
AtomicIntegerArray int原子類陣列
AtomicLongArray long原子類陣列
AtomicReferenceArray 引用原子類陣列
AtomicIntegerFieldUpdater int原子類物件欄位
AtomicLongFieldUpdater long原子類物件欄位
AtomicReferenceFieldUpdater 引用原子類物件欄位
AtomicMarkableReference AtomicReference在使用時會出現aba問題,通過一個識別符號號判斷是否被改過
AtomicStampedReference AtomicReference在使用時會出現aba問題,通過一個int標識是否被改過