定义
LongAdder
LongAdder是JDK 8加入的高性能原子计数器,用于解决在AtomicLong高并发状态下性能差的问题。
核心思想
- 单线程/低并发:通过CAS更新基础字段
base。 - 高并发/有竞争:将线程分散到不同槽位(
Cell[]),每个线程对其中一个槽位进行累加。 - 统计结果:sum() = base + (
cells[i].value)。
数据结构
LongAdder继承了Striped64,Striped64是原子累加的核心类。
abstract class Striped64 extends Number {
// 无竞争时使用的基础值
transient volatile long base;
// 自旋锁标志位(0 表示无锁,1 表示有锁),用于控制 cells 初始化或扩容
transient volatile int cellsBusy;
// 槽数组(Cell 数组,懒加载,大小为 2 的幂次方,上限通常为 CPU 核心数)
transient volatile Cell[] cells;
// 内部类 Cell
@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);
}
}
}核心操作
定位Cell
- 通过
ThreadLocalRandom.getProbe()获取probe值。 - 通过
(n - 1) & probe得到下标。 - 访问
cells[index]。
扩容
扩容条件:
- 当前槽位CAS失败
cells长度<NCPU- 当前
cells没有被其他线程占用(cellsBusy可获取)
求和
sum() = base + (cells[i].value)
求和过程中无锁,所以非强一致性,但性能好。