定义


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

  1. 通过ThreadLocalRandom.getProbe()获取probe值。
  2. 通过(n - 1) & probe得到下标。
  3. 访问cells[index]。

扩容

扩容条件:

  1. 当前槽位CAS失败
  2. cells 长度< NCPU
  3. 当前cells没有被其他线程占用(cellsBusy 可获取)

求和

sum() = base + (cells[i].value)
求和过程中无锁,所以非强一致性,但性能好。