原子類的實現(JDK1.8)

Java提供的原子類是靠CAS+volatile 實現的,CAS 是一種樂觀鎖。

 

源碼分析(以AtomicInteger爲例)

 private volatile int value;



//遞增加detla
    public final int getAndAdd(int delta) {
        //三個參數,1、當前的實例 2、value實例變量的偏移量 3、當前value要加上的數(value+delta)。
        return unsafe.getAndAddInt(this, valueOffset, delta);
    }

    //遞增加1
    public final int incrementAndGet() {
        return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
    }

 

Unsafe源碼解析

下面分析下Unsafe 類中的實現。代碼反編譯出來的。

public final int getAndAddInt(Object paramObject, long paramLong, int paramInt)
  {
    int i;
    do
      i = getIntVolatile(paramObject, paramLong);
    while (!compareAndSwapInt(paramObject, paramLong, i, i + paramInt));
    return i;
  }

  public final long getAndAddLong(Object paramObject, long paramLong1, long paramLong2)
  {
    long l;
    do
      l = getLongVolatile(paramObject, paramLong1);
    while (!compareAndSwapLong(paramObject, paramLong1, l, l + paramLong2));
    return l;
  }

  public final int getAndSetInt(Object paramObject, long paramLong, int paramInt)
  {
    int i;
    do
      i = getIntVolatile(paramObject, paramLong);
    while (!compareAndSwapInt(paramObject, paramLong, i, paramInt));
    return i;
  }

  public final long getAndSetLong(Object paramObject, long paramLong1, long paramLong2)
  {
    long l;
    do
      l = getLongVolatile(paramObject, paramLong1);
    while (!compareAndSwapLong(paramObject, paramLong1, l, paramLong2));
    return l;
  }

  public final Object getAndSetObject(Object paramObject1, long paramLong, Object paramObject2)
  {
    Object localObject;
    do
      localObject = getObjectVolatile(paramObject1, paramLong);
    while (!compareAndSwapObject(paramObject1, paramLong, localObject, paramObject2));
    return localObject;
  }

內部使用自旋的方式進行CAS更新(while循環進行CAS更新,如果更新失敗,則循環再次重試)

從Unsafe類中發現,原子操作其實只支持下面三個方法。

  public final native boolean compareAndSwapObject(Object paramObject1, long paramLong, Object paramObject2, Object paramObject3);

  public final native boolean compareAndSwapInt(Object paramObject, long paramLong, int paramInt1, int paramInt2);

  public final native boolean compareAndSwapLong(Object paramObject, long paramLong1, long paramLong2, long paramLong3);

我們發現Unsafe只提供了3種CAS方法:compareAndSwapObject、compareAndSwapInt和compareAndSwapLong。都是native方法。

 

AtomicBoolean 源碼解析

public class AtomicBoolean implements java.io.Serializable {
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long valueOffset;

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

    private volatile int value;

    public AtomicBoolean(boolean initialValue) {
        value = initialValue ? 1 : 0;
    }
    public final boolean compareAndSet(boolean expect, boolean update) {
        int e = expect ? 1 : 0;
        int u = update ? 1 : 0;
        return unsafe.compareAndSwapInt(this, valueOffset, e, u);
    }
    ...
}

從AtomicBoolean源碼,發現他底層也是使用volatile類型的int 變量,跟AtomicInteger 實現方式一樣,只不過是把Boolean轉換成 0和1進行操作。

所以原子更新char、float和double變量也可以轉換成int 或long來實現CAS的操作。

 

原文:

https://www.jianshu.com/p/a533cbb740c6


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章