AtomicInteger类源码剖析 一、AtomicInteger类的简介 AtomicInteger用于原子递增计数器
等应用程序,不能用作Integer的替代品。然而,此类确实扩展了Number
,以允许处理基于数字的类的工具和实用程序进行统一访问。
二、AtomicInteger类的属性
AtomicInteger
类主要利用CAS(compare and swap)+volatile和native方法来保证原子操作,从而避免synchronized的高开销,执行效率大为提升。
CAS的原理是拿期望的值和原本的一个值作比较,如果相同则更新成新的值。UnSafe类的objectFieldOffset()
方法是一个本地方法,这个方法是用来拿到“原来的值”的内存地址。另外value是一个volatile变量,在内存中可见,因此JVM可以保证任何时刻任何线程总能拿到该变量的最新值。
1 2 3 4 5 6 private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();private static final long VALUE = U.objectFieldOffset(AtomicInteger.class, "value" );private volatile int value;
三、AtomicInteger类的创建 1 2 3 4 5 6 7 8 9 10 public AtomicInteger (int initialValue) { value = initialValue; } public AtomicInteger () {} public final void set (int newValue) { value = newValue; }
常见的使用场景无非是调用AtomicInteger的有参构造函数设置初始值,或者调用AtomicInteger的无参构造函数但随后立刻调用set方法设置初始值。
四、AtomicInteger类的重要方法 1.简单的常用方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 public final int get () { return value; } public final int getAndSet (int newValue) { return U.getAndSetInt(this , VALUE, newValue); } public final boolean compareAndSet (int expectedValue, int newValue) { return U.compareAndSetInt(this , VALUE, expectedValue, newValue); } public final int getAndIncrement () { return U.getAndAddInt(this , VALUE, 1 ); } public final int getAndDecrement () { return U.getAndAddInt(this , VALUE, -1 ); } public final int getAndAdd (int delta) { return U.getAndAddInt(this , VALUE, delta); } public final int incrementAndGet () { return U.getAndAddInt(this , VALUE, 1 ) + 1 ; } public final int decrementAndGet () { return U.getAndAddInt(this , VALUE, -1 ) - 1 ; } public final int addAndGet (int delta) { return U.getAndAddInt(this , VALUE, delta) + delta; }
2.复杂的常用方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 public final int getAndUpdate (IntUnaryOperator updateFunction) { int prev = get(), next = 0 ; for (boolean haveNext = false ;;) { if (!haveNext) next = updateFunction.applyAsInt(prev); if (weakCompareAndSetVolatile(prev, next)) return prev; haveNext = (prev == (prev = get())); } } public final int updateAndGet (IntUnaryOperator updateFunction) { int prev = get(), next = 0 ; for (boolean haveNext = false ;;) { if (!haveNext) next = updateFunction.applyAsInt(prev); if (weakCompareAndSetVolatile(prev, next)) return next; haveNext = (prev == (prev = get())); } } public final int getAndAccumulate (int x, IntBinaryOperator accumulatorFunction) { int prev = get(), next = 0 ; for (boolean haveNext = false ;;) { if (!haveNext) next = accumulatorFunction.applyAsInt(prev, x); if (weakCompareAndSetVolatile(prev, next)) return prev; haveNext = (prev == (prev = get())); } } public final int accumulateAndGet (int x, IntBinaryOperator accumulatorFunction) { int prev = get(), next = 0 ; for (boolean haveNext = false ;;) { if (!haveNext) next = accumulatorFunction.applyAsInt(prev, x); if (weakCompareAndSetVolatile(prev, next)) return next; haveNext = (prev == (prev = get())); } }
3.实现的父类方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public int intValue () { return get(); } public long longValue () { return (long )get(); } public float floatValue () { return (float )get(); } public double doubleValue () { return (double )get(); }
4.依赖的底层方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public final int getAndSetInt (Object o, long offset, int newValue) { int v; do { v = getIntVolatile(o, offset); } while (!compareAndSwapInt(o, offset, v, newValue)); return v; } 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 native boolean compareAndSwapInt (Object o, long offset, int expected, int x) ;
总结,AtomicInteger类底层依赖的就是volatile的可见性+Unfase的CAS+失败自旋重试完成原子更新的!