java.util.concurrent.atomic與CAS詳解

1、CAS(Compare And Swap)java

顧名思義,CAS就是比較與交換。具體解釋以下:數組

CAS 操做包含三個操做數 —— 內存位置(V)、預期原值(A)和新值(B)。若是內存位置的值與預期原值相匹配,那麼處理器會自動將該位置值更新爲新值。不然,處理器不作任何操做。不管哪一種狀況,它都會在 CAS 指令以前返回該位置的值。CAS 有效地說明了 「 我認爲位置 V 應該包含值 A;若是包含該值,則將 B 放到這個位置;不然,不要更改該位置,只告訴我這個位置如今的值便可。」 this

2、java.ut l.concurrent.atomicatom

【標量類】:AtomicBoolean,AtomicInteger,AtomicLong,AtomicReference.net

【數組類】:AtomicIntegerArray,AtomicLongArray,AtomicReferenceArraycode

【更新器類】:AtomicLongFieldUpdater,AtomicIntegerFieldUpdater,AtomicReferenceFieldUpdater對象

【複合變量類】:AtomicMarkableReference,AtomicStampedReferenceblog

就拿第一組來講,均採用了CAS方式。內存

3、源碼解讀ci

以AtomicInteger爲例,源碼以下:

private static final Unsafe unsafe = Unsafe.getUnsafe();
     private static final long valueOffset;

     static {
       try {
         valueOffset = unsafe.objectFieldOffset
             (AtomicInteger.class.getDeclaredField("value"));
       } catch (Exception ex) { throw new Error(ex); }
     }

     private volatile int value;

     ......

       /**
     * Atomically sets to the given value and returns the old value.
     *
     * @param newValue the new value
     * @return the previous value
     */
    public final int getAndSet(int newValue) {
        for (;;) {
            int current = get();
            if (compareAndSet(current, newValue))
                return current;
        }
    }

    /**
     * Atomically sets the value to the given updated value
     * if the current value {@code ==} the expected value.
     *
     * @param expect the expected value
     * @param update the new value
     * @return true if successful. False return indicates that
     * the actual value was not equal to the expected value.
     */
    public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

從上述代碼能夠看到,AtomicInteger獲取value值是經過Unsafe類的objectFieldOffset()方法,而後調用Unsafe類的compareAndSwapInt()方法完成CAS操做。下面看看Unsafe這幾個方法,以下:

objectFieldOffset():

/***
   * Returns the memory address offset of the given static field.
   * The offset is merely used as a means to access a particular field
   * in the other methods of this class.  The value is unique to the given
   * field and the same value should be returned on each subsequent call.
   * 返回指定靜態field的內存地址偏移量,在這個類的其餘方法中這個值只是被用做一個訪問
   * 特定field的一個方式。這個值對於 給定的field是惟一的,而且後續對該方法的調用都應該
   * 返回相同的值。
   *
   * @param field the field whose offset should be returned.
   *              須要返回偏移量的field
   * @return the offset of the given field.
   *              指定field的偏移量
   */
  public native long objectFieldOffset(Field field);

compareAndSwapInt():

/***
   * Compares the value of the integer field at the specified offset
   * in the supplied object with the given expected value, and updates
   * it if they match.  The operation of this method should be atomic,
   * thus providing an uninterruptible way of updating an integer field.
   * 在obj的offset位置比較integer field和指望的值,若是相同則更新。這個方法
   * 的操做應該是原子的,所以提供了一種不可中斷的方式更新integer field。
   * 
   * @param obj the object containing the field to modify.
   *            包含要修改field的對象
   * @param offset the offset of the integer field within <code>obj</code>.
   *            <code>obj</code>中整型field的偏移量
   * @param expect the expected value of the field.
   *            但願field中存在的值
   * @param update the new value of the field if it equals <code>expect</code>.
   *            若是指望值expect與field的當前值相同,設置filed的值爲這個新值
   * @return true if the field was changed.
   *            若是field的值被更改返回true
   */
  public native boolean compareAndSwapInt(Object obj, long offset, int expect, int update);

下面看看compareAndSwapInt()方法具體源碼,以下:

jboolean
sun::misc::Unsafe::compareAndSwapInt (jobject obj, jlong offset, jint expect, jint update)
{
  jint *addr = (jint *)((char *)obj + offset);
  return compareAndSwap (addr, expect, update);
}
static inline bool
compareAndSwap (volatile jint *addr, jint old, jint new_val)
{
  jboolean result = false;
  spinlock lock;
  if ((result = (*addr == old)))
    *addr = new_val;
  return result;
}

實現原理就是內存位置的值與指望值相同則將該內存位置的值更新爲新值。

Unsafe類的更多源碼解釋:http://blog.csdn.net/zgmzyr/article/details/8902683

相關文章
相關標籤/搜索