LongAdder的基本思想就是分散热点,将value值分散到一个Cell数组中,不同线程会命中到数组的不同槽中
各个线程只对自己槽中的值进行CAS操作,最终将各个槽中的变量值累加
Striped64(LongAdder是Striped64的子类)
static final class Cell{}:内部类
static final int NCPU:CPU数量,即cells数组的最大长度
transient volatile Cell[] cells:2的幂次方,方便位运算
transient volatile long base:基础value值,并发较低时通过CAS更新
transient volatile int cellsBusy:创建或者扩容cells数组时使用的自旋锁变量调整单元格大小
LongAdder中的increment()
public void increment() {
add(1L);
}
increment()中调用add()
public void add(long x) {
Cell[] as; //as表示cells引用
long b, v; //b表示获取的base值,v表示当前线程hash到的Cell中存储的值
int m; //m表示cells数组的长度
Cell a;//a表示当前线程hash到的cell单元格
//如果(as = cells) != null为true,则表示已扩容
//如果!casBase(b = base, b + x)为true,则表示CAS操作失败
if ((as = cells) != null || !casBase(b = base, b + x)) {
//根据uncontended决定是否扩容
boolean uncontended = true;
//判断as == null或(m = as.length - 1) < 0是否为true
//如果(a = as[getProbe() & m]) == null为true,则表示当前线程所在的Cell为空,需要初始化一个Cell
//如果!(uncontended = a.cas(v = a.value, v + x))为true,则表示扩容后的槽位CAS操作失败
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);
}
}
add()中调用longAccumulate()
final void longAccumulate(long x, LongBinaryOperator fn,
boolean wasUncontended) {
//存储线程的hash值
int h;
//如果线程的hash值为0,说明未初始化
if ((h = getProbe()) == 0) {
//为当前线程计算一个hash值
ThreadLocalRandom.current(); // force initialization
//重新获取hash值
h = getProbe();
//将wasUncontended改为true,表示不存在竞争
wasUncontended = true;
}
boolean collide = false; // True if last slot nonempty
for (;;) {
Cell[] as; Cell a; int n; long v;
//cells已经被初始化
if ((as = cells) != null && (n = as.length) > 0) {
//如果(a = as[(n - 1) & h]) == null,则表示需要进行初始化
if ((a = as[(n - 1) & h]) == null) {
//判断是否为无锁状态
if (cellsBusy == 0) { // Try to attach new Cell
Cell r = new Cell(x); // Optimistically create
//再次判断是否为无锁状态,并将cellsBusy设置为1
if (cellsBusy == 0 && casCellsBusy()) {
boolean created = false;
try { // Recheck under lock
Cell[] rs; int m, j;
//初始化
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;
}
//将wasUncontended改为true,允许重新竞争,执行advanceProbe(h)
else if (!wasUncontended) // CAS already known to fail
wasUncontended = true; // Continue after rehash
//CAS操作成功以后跳出循环
else if (a.cas(v = a.value, ((fn == null) ? v + x :
fn.applyAsLong(v, x))))
break;
//判断是否大于CPU的核数,如果大于CPU的核数则无需扩容
else if (n >= NCPU || cells != as)
collide = false; // At max size or stale
//允许扩容
else if (!collide)
collide = true;
//判断是否为无锁状态,并将cellsBusy设置为1
else if (cellsBusy == 0 && casCellsBusy()) {
try {
//扩容
if (cells == as) { // Expand table unless stale
//扩容大小为之前的两倍
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没有加锁且没有初始化,尝试对它进行加锁,并初始化cells数组
//如果cellsBusy == 0,则表示无锁状态
//如果cells == as,则表示没有初始化
//casCellsBusy()将cellsBusy设置为1
else if (cellsBusy == 0 && cells == as && casCellsBusy()) {
boolean init = false;
try { // Initialize table
//再次判断cells == as,则表示没有初始化
if (cells == as) {
Cell[] rs = new Cell[2];
rs[h & 1] = new Cell(x);
cells = rs;
init = true;
}
} finally {
cellsBusy = 0;
}
if (init)
break;
}
//cells正在进行初始化,直接在base上进行累加操作
else if (casBase(v = base, ((fn == null) ? v + x :
fn.applyAsLong(v, x))))
break; // Fall back on using base
}
}
LongAdder中的sum()
public long sum() {
Cell[] as = cells; Cell a;
long sum = base;
//将Cell数组中的value和base累加作为返回值
if (as != null) {
for (int i = 0; i < as.length; ++i) {
if ((a = as[i]) != null)
sum += a.value;
}
}
return sum;
}