AtomicInteger源碼註釋

AtomicInteger源碼

在java.util.concurrent.atomic包下提供了大量的原子類,這裏以AtomicInteger源碼爲例,添加了一些註釋,我的理解,供參考;java

其中比較重要的一個概念是CAS操做,現代CPU已普遍支持,在JDK的AtomicInteger類中是調用了Unsafe類的compareAndSwapInt方法實現的,代碼(jdk1.7.0_79)以下:安全

package java.util.concurrent.atomic;
import sun.misc.Unsafe;


public class AtomicInteger extends Number implements java.io.Serializable {
    //序列化相關
    private static final long serialVersionUID = 6214790243416807050L;

    // JDK裏使用的一個工具類對象,提供一些不安全的操做的方法,通常不會在本身的程序中使用該類
    //在這裏主要用到其中的objectFieldOffset、putOrderedInt、compareAndSwapInt方法
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    
    //value成員屬性的內存地址相對於對象內存地址的偏移量
    private static final long valueOffset;

    static {
      try {
        //初始化valueOffset,經過unsafe.objectFieldOffset方法獲取成員屬性value內存地址相對於對象內存地址的偏移量
        valueOffset = unsafe.objectFieldOffset(AtomicInteger.class.getDeclaredField("value"));
      } catch (Exception ex) { throw new Error(ex); }
    }
    //int的值,設爲volatile,保證線程之間的可見性
    private volatile int value;

    /**
     * 構造方法,傳入指定int值
     *
     * @param initialValue the initial value
     */
    public AtomicInteger(int initialValue) {
        value = initialValue;
    }

    /**
     * 構造方法,使用默認值0
     */
    public AtomicInteger() {
    }

    /**
     * 獲取int值
     */
    public final int get() {
        return value;
    }

    /**
     * 設爲指定值
     */
    public final void set(int newValue) {
        value = newValue;
    }

    /**
     * 最終設爲指定值,但其它線程不能立刻看到變化,會延時一會
     */
    public final void lazySet(int newValue) {
        unsafe.putOrderedInt(this, valueOffset, newValue);
    }

    /**
     * 以原子方式設置爲給定值,並返回舊值
     */
    public final int getAndSet(int newValue) {
        //樂觀鎖,非阻塞同步方式,循環調用compareAndSet,直到成功
        for (;;) {
            int current = get();
            //CAS操做,期待值current與內存中的值比較,相等的話設爲newValue值
            //不然下個循環,調用get()獲取current值,繼續執行CAS操做直到成功
            if (compareAndSet(current, newValue))
                return current;
        }
    }

    /**
     * CAS操做,現代CPU已普遍支持,是一種原子操做;
     * 簡單地說,當期待值expect與valueOffset地址處的值相等時,設置爲update值
     */
    public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

    /**
     * 查看源碼,與compareAndSet方法一致,不解??
     */
    public final boolean weakCompareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

    /**
     * 原子操做,自增,返回舊值
     */
    public final int getAndIncrement() {
        for (;;) {
            int current = get();
            int next = current + 1;
            if (compareAndSet(current, next))
                return current;
        }
    }

    /**
     * 原子操做,自減,返回舊值
     */
    public final int getAndDecrement() {
        for (;;) {
            int current = get();
            int next = current - 1;
            if (compareAndSet(current, next))
                return current;
        }
    }

    /**
     * 原子操做,加上一個數,返回舊值
     */
    public final int getAndAdd(int delta) {
        for (;;) {
            int current = get();
            int next = current + delta;
            if (compareAndSet(current, next))
                return current;
        }
    }

    /**
     * 原子操做,自增,返回新值
     */
    public final int incrementAndGet() {
        for (;;) {
            int current = get();
            int next = current + 1;
            if (compareAndSet(current, next))
                return next;
        }
    }

    /**
     * 原子操做,自減,返回新值
     */
    public final int decrementAndGet() {
        for (;;) {
            int current = get();
            int next = current - 1;
            if (compareAndSet(current, next))
                return next;
        }
    }

    /**
     * 原子操做,加上一個數,返回新值
     */
    public final int addAndGet(int delta) {
        for (;;) {
            int current = get();
            int next = current + delta;
            if (compareAndSet(current, next))
                return next;
        }
    }

    /**
     * Returns the String representation of the current value.
     * @return the String representation of the current value.
     */
    public String toString() {
        return Integer.toString(get());
    }


    public int intValue() {
        return get();
    }

    public long longValue() {
        return (long)get();
    }

    public float floatValue() {
        return (float)get();
    }

    public double doubleValue() {
        return (double)get();
    }

}
相關文章
相關標籤/搜索