併發(2) 原子類

  java併發包中提供了一些原子變量類,這些原子變量類提供的方法自己就是一個原子操做。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方法來設置改值。this

  unsafe的compareAndSet方法作了什麼呢?他首先會去比較當前值是否是預期的值,若是不是返回false,若是是設置新值並返回true。spa

  這種方式也叫作CAS,他不只是原子類的底層實現方式,也是java顯式鎖的底層實現方式。就是在設置新值以前判斷當前是否仍是老值,若是是則設置新值,若是不是則從新計算新值後再嘗試設置。當CAS實現原子性的基礎是compareAndSet自己是一個原子操做,而且提供了內存可見性線程

原子類code

原子類 說明
AtomicBoolean boolean原子類 
AtomicInteger int原子類
AtomicLong long原子類
AtomicReference 引用原子類
AtomicIntegerArray int原子類數組
AtomicLongArray long原子類數組
AtomicReferenceArray 引用原子類數組
AtomicIntegerFieldUpdater int原子類對象字段
AtomicLongFieldUpdater long原子類對象字段
AtomicReferenceFieldUpdater 引用原子類對象字段
AtomicMarkableReference AtomicReference在使用時會出現aba問題,經過一個標識符號判斷是否被改過
AtomicStampedReference AtomicReference在使用時會出現aba問題,經過一個int標識是否被改過
相關文章
相關標籤/搜索