LongAdder
LongAdder。 有两个, 一个base, 一个cell 数组, 如果当前线程不存在竞争,都是线性的,那么就会一直累加到base里面, 如果存在竞争, 就会分发给cell 数组,,最后cell 数组求和+ base 就是最终的结果。
AtomicLong 则是通过不停的cas 去尝试改变,LongAdder 采用的是以空间换时间的方式
public void add(long x) {
Cell[] as; long b, v; int m; Cell a;
// 条件-: true: 如果cells数组不为空, 需要初始化cells数组
// false 如果cells数组为空
// 条件二: true: 进行cas 失败 ,需要扩容 或者 重试
//。 false。cas成功
// 如果当前不存在线程竞争关系,那么对于base 的cas 操作一定会成功, 如果失败,就代表失败,就需要进行cells数组初始化
if ((as = cells) != null || !casBase(b = base, b + x)) {
//。如何进入?
//。当存在竞争关系的时候, cas 操作失败, 需要cells 数组进行初始化 , 会进入
// uncontended. 为true 代表不存在竞争
boolean uncontended = true;
//。条件-: true: as 为null, 没有被初始化。 原因: 防止多线程情况下,有线程已经进行初始化了,但是其他线程哪里的as还是null
//。 false: as 被初始化
// 条件二: getProbe(). 计算hash值
//。 true: hash值 & m =。分配的数组下标, 如果为null ,代表该位置没有累加运算过, 就需要new Cell
//。 false: 不为null, 已经做过了
//。条件三: true: cas 操作失败
//。 false: cas 操作成功
if (as == null || (m = as.length - 1) < 0 ||
(a = as[getProbe() & m]) == null ||
!(uncontended = a.cas(v = a.value, v + x)))
//。进入的三种情况, cells 没有进行初始化,
// 下标对应位置没有被使用过, 需要new 一个Cell 对象
// cas 操作失败
longAccumulate(x, null, uncontended);
}
}
//。x。 要累加的值
//。wasUncontended。 是否cas 操作失败过
final void longAccumulate(long x, LongBinaryOperator fn,
boolean wasUncontended) {
// hash 值
int h;
//。如果没有进行分配
if ((h = getProbe()) == 0) {
// 初始化
ThreadLocalRandom.current(); // force initialization
//。分配hash值
h = getProbe();
// 默认分配到0下标,也就是没有发生冲突
wasUncontended = true;
}
//。代表该下标是否发生冲突
boolean collide = false; // True if last slot nonempty
//。自旋
for (;;) {
Cell[] as; Cell a; int n; long v;
//。条件: true: cells 被初始化了, 将对应数据写入cells 中
if ((as = cells) != null && (n = as.length) > 0) {
//。如果当前分配下标为 null, 说明需要new 一个Cell 对象
if ((a = as[(n - 1) & h]) == null) {
//。当前锁是否被占用, 0 为没有被占用
if (cellsBusy == 0) { // Try to attach new Cell
Cell r = new Cell(x); // Optimistically create
//。 尝试获取锁, 获取到了锁
if (cellsBusy == 0 && casCellsBusy()) {
boolean created = false;
try { // Recheck under lock
Cell[] rs; int m, j;
// 条件一: cells 没有被其他线程改变
// 条件二: 分配的下标没有被使用
if ((rs = cells) != null &&
(m = rs.length) > 0 &&
rs[j = (m - 1) & h] == null) {
rs[j] = r;
created = true;
}
} finally {
cellsBusy = 0;
}
if (created)
break;
continue; // Slot is now non-empty
}
}
collide = false;
}
// 条件: true: 发生冲突,cas 失败
// false: 没有发生过冲突
else if (!wasUncontended) // CAS already known to fail
wasUncontended = true; // Continue after rehash
//。条件: true: 进行cas 操作 成功, 就break
// false: 进行cas 失败
else if (a.cas(v = a.value, ((fn == null) ? v + x :
fn.applyAsLong(v, x))))
break;
//。如果当前cells 数组长度 大于CPU数量,或者 cells 已经被其他线程扩容,或者正在扩容
else if (n >= NCPU || cells != as)
//。扩容标记为false
collide = false; // At max size or stale
//。扩容标记为 true
else if (!collide)
collide = true;
//。如果当前线程获取到锁
else if (cellsBusy == 0 && casCellsBusy()) {
try {
//。判断cells 有没有被操作过
if (cells == as) { // Expand table unless stale
// 进行扩容, 扩大2倍
Cell[] rs = new Cell[n << 1];
for (int i = 0; i < n; ++i)
rs[i] = as[i];
cells = rs;
}
} finally {
cellsBusy = 0;
}
collide = false;
continue; // Retry with expanded table
}
h = advanceProbe(h);
}
//。如果线程获取到锁, 并且cells 数组没有被扩容
else if (cellsBusy == 0 && cells == as && casCellsBusy()) {
boolean init = false;
try { // Initialize table
//。如果没有其他线程改变, 就进行初始化
if (cells == as) {
Cell[] rs = new Cell[2];
rs[h & 1] = new Cell(x);
cells = rs;
init = true;
}
} finally {
cellsBusy = 0;
}
if (init)
break;
}
//。 进行cas。操作, 尝试加载 base 上面
else if (casBase(v = base, ((fn == null) ? v + x :
fn.applyAsLong(v, x))))
break; // Fall back on using base
}
}