/** * Atomically increments by one the current value. * * @return the updated value */ public final long incrementAndGet() { return unsafe.getAndAddLong(this, valueOffset, 1L) + 1L; }
public final long getAndAddLong(Object var1, long var2, long var4) { long var6; do { var6 = this.getLongVolatile(var1, var2); } while(!this.compareAndSwapLong(var1, var2, var6, var6 + var4)); // 关注重点:if(var2 == var6) return var6; }
var1
调用原方法 incrementAndGet
即自身的对象var2
原对象当前(工做内存中的)值var4
要加上去的值var6
调用底层方法 getLongVolatile
得到当前(主内存中的)值,若是没其余线程修改即与 var2
相等var2
与 var6
为何可能会不同?html
var2
与主内存中的值 var6
之间的可能不同(JMM)// 获取主内存里的值 public native long getLongVolatile(Object var1, long var2); // CAS 操做 public final native boolean compareAndSwapLong(Object var1, long var2, long var4, long var6);
native关键字说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是在用其余语言(如 C 和 C++)实现的文件中。Java 语言自己不能对操做系统底层进行访问和操做,可是能够经过JNI接口调用其余语言来实现对底层的访问。
public void increment() { add(1L); } public void add(long x) { Cell[] as; long b, v; int m; Cell a; if ((as = cells) != null || !casBase(b = base, b + x)) { boolean uncontended = true; if (as == null || (m = as.length - 1) < 0 || (a = as[getProbe() & m]) == null || !(uncontended = a.cas(v = a.value, v + x))) longAccumulate(x, null, uncontended); // <- 重点 } }
Cell
类,是一个普通的二元算术累积单元,它在 Striped64
里面。Striped64
这个类使用分段的思想,来尽可能平摊并发压力(相似1.7及之前版本的 ConcurrentHashMap.Segment
)。compareAndSwapLong
来更新值。/** * Padded variant of AtomicLong supporting only raw accesses plus CAS. * * JVM intrinsics note: It would be possible to use a release-only * form of CAS here, if it were provided. */ @sun.misc.Contended static final class Cell { volatile long value; Cell(long x) { value = x; } final boolean cas(long cmp, long val) { return UNSAFE.compareAndSwapLong(this, valueOffset, cmp, val); } // Unsafe mechanics private static final sun.misc.Unsafe UNSAFE; private static final long valueOffset; static { try { UNSAFE = sun.misc.Unsafe.getUnsafe(); Class<?> ak = Cell.class; valueOffset = UNSAFE.objectFieldOffset (ak.getDeclaredField("value")); } catch (Exception e) { throw new Error(e); } } }
Long
映射到 Cell[]
数组里面,经过 Hash
等算法映射到其中一个数字进行计数,而最终的计数结果就是其求和累加。在低并发的时候,经过对 base
的直接更新,能够很好地保证和 Atomic
性能的基本一致;而在高并发的时候,则将单点的更新压力分散到各个节点上,提高了性能。AtomicLong
适用于序号生成,这种状况下须要准确的、全局惟一的数值;但在高并发状况下的计数操做,使用 AtomicLong
时会因线程竞争致使失败白白循环一次;失败次数越多,循环次数也越多。此时使用LongAdder
能更好地提高性能。LongAdder
适用于高并发状况下的计数操做,利用与 JDK1.7 ConcurrentHashMap
类似的原理,以空间换时间,提升了实际的计数效率。固然,线程竞争很低的状况下进行计数,使用 AtomicLong
仍是更简单更直接,而且效率稍微高一些。注意:CAS 是 sun.misc.Unsafe
中提供的操做,只对 int、long、对象类型(引用或者指针)提供了这种操做,其余类型都须要转化为这三种类型才能进行 CAS 操做。(例如 DoubleAdder
就是 LongAdder
的简单改造,主要的变化就是用 Double.longBitsToDouble
和 Double.doubleToRawLongBits
对底层的8字节数据进行 long <=> double
转换,存储的时候使用 long 型,计算的时候转化为 double 型。)java
参考资料算法