java源码-AtomicInteger
开篇 AtomicInteger位于java.util.concurrent.atomic包下,是java提供给的可以保证数据的原子性操作的一个类。 Atomicxxxx系列主要核心在于Unsafe这个类的运用保证线程安全,而Unsafe这个类应该是通过JNI调用的底层实现。 关于unsafe类可以看看揭秘sun.misc.Unsafe,虽然我还是没怎么看懂。记住unsafe这个东西很重要,不过据说在jdk9之后应该会被弃用了。 AtomicInteger类构造器 AtomicInteger类构造器有两个: 无参构造函数采用默认值初始化为0 有参数构造函数直接用initialValue来value的 AtomicInteger的关键逻辑在于static代码快中通过unsafe接口初始化value的内存地址,后续直接通过内存地址进行操作。 另外我们需要注意到value是用volatile进行修饰保证变量的可见性,这个有空一定要仔细研究研究。 public class AtomicInteger extends Number implements java.io.Serializable { private static final long serialVersionUID = 6214790243416807050L; // setup to use Unsafe.compareAndSwapInt for updates 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; // value值初始化为initialValue public AtomicInteger(int initialValue) { value = initialValue; } // value的值为默认值为0 public AtomicInteger() { } } AtomicInteger的get操作 AtomicInteger的get操作还是比较有意思的,总共非几大类: get()方法直接返回值 getAndIncrement()、getAndDecrement()、getAndAdd()、getAndUpdate()先返回旧值后对旧值执行加减操作。 incrementAndGet()、decrementAndGet()、addAndGet()、updateAndGet()先执行加减操作后返回新值。 底层操作unsafe.getAndAddInt()的实现细节借助于unsafe的compareAndSwapInt()方法保证只有在旧值为v的情况下才能更新为v+delta值。 public final int getAndAddInt(Object o, long offset, int delta) { int v; do { v = getIntVolatile(o, offset); } while (!compareAndSwapInt(o, offset, v, v + delta)); return v; } --------------------------------------------------------------- public final int get() { return value; } public final int getAndIncrement() { return unsafe.getAndAddInt(this, valueOffset, 1); } public final int getAndDecrement() { return unsafe.getAndAddInt(this, valueOffset, -1); } public final int getAndAdd(int delta) { return unsafe.getAndAddInt(this, valueOffset, delta); } public final int getAndUpdate(IntUnaryOperator updateFunction) { int prev, next; do { prev = get(); next = updateFunction.applyAsInt(prev); } while (!compareAndSet(prev, next)); return prev; } public final int getAndAccumulate(int x, IntBinaryOperator accumulatorFunction) { int prev, next; do { prev = get(); next = accumulatorFunction.applyAsInt(prev, x); } while (!compareAndSet(prev, next)); return prev; } --------------------------------------------------------------- public final int incrementAndGet() { return unsafe.getAndAddInt(this, valueOffset, 1) + 1; } public final int decrementAndGet() { return unsafe.getAndAddInt(this, valueOffset, -1) - 1; } public final int addAndGet(int delta) { return unsafe.getAndAddInt(this, valueOffset, delta) + delta; } public final int updateAndGet(IntUnaryOperator updateFunction) { int prev, next; do { prev = get(); next = updateFunction.applyAsInt(prev); } while (!compareAndSet(prev, next)); return next; } public final int accumulateAndGet(int x, IntBinaryOperator accumulatorFunction) { int prev, next; do { prev = get(); next = accumulatorFunction.applyAsInt(prev, x); } while (!compareAndSet(prev, next)); return next; } AtomicInteger的set操作 AtomicInteger的set操作基本上也分为两大类: 直接set设置value值 通过unsafe的api接口实现原子性写操作 public final int getAndAddInt(Object o, long offset, int delta) { int v; do { v = getIntVolatile(o, offset); } while (!compareAndSwapInt(o, offset, v, v + delta)); return v; } ------------------------------------------------------------------ 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) { return unsafe.getAndSetInt(this, valueOffset, newValue); } public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); } public final boolean weakCompareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); } 参考文章 揭秘sun.misc.Unsafe非阻塞同步算法与CAS(Compare and Swap)无锁算法为什么volatile不能保证原子性而Atomic可以?彻底了解内存屏障