AtomicInteger源码注释

AtomicInteger源码

在java.util.concurrent.atomic包下提供了大量的原子类,这里以AtomicInteger源码为例,添加了一些注释,个人理解,供参考;

其中比较重要的一个概念是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();
    }

}

 

posted @ 2016-04-05 22:15  风一样的码农  阅读(...)  评论(...编辑  收藏