LongAdder 在高并发下比 AtomicLong 更高效,通过 base+cells 分段机制将单点竞争分散为多点低冲突操作,add() 无锁低开销,sum() 延迟聚合适合统计场景,以空间换时间提升吞吐。

LongAdder 在高并发场景下比 AtomicLong 更高效,核心在于它把“单点竞争”变成了“多点分散”,避免了大量线程挤在同一个变量上反复 CAS 自旋。
竞争模型从集中到分散
AtomicLong 所有线程都争抢一个 volatile long 变量,每次 increment 都要 CAS 更新它。高并发时失败率飙升,线程不断重试,CPU 白耗、缓存行频繁失效(MESI 协议引发总线风暴)。LongAdder 则用 base + cells 数组实现分段:线程根据自身 probe 值哈希到某个 Cell 上操作,彼此互不干扰,大幅降低冲突概率。
写操作无锁且低开销
LongAdder 的 add() 和 increment() 不返回当前值,也不保证立即反映全局状态——它只负责往某个 Cell 里加数,几乎不阻塞。Cell 内部仍用 CAS,但因竞争被摊薄,成功率极高;即使某 Cell 正忙,线程也会尝试其他 Cell 或退回到 base,不会死等。
读操作延迟聚合,适合统计类场景
sum() 是读时聚合:遍历所有非空 Cell,加上 base 值。这意味着它不是强一致的快照——并发写入中调用 sum() 可能漏掉尚未 flush 的更新。但这恰恰契合监控指标、QPS 统计等场景:你不需要毫秒级精确值,而需要高吞吐下的近似总量。
立即学习“Java免费学习笔记(深入)”;
内存与性能的务实权衡
LongAdder 惰性初始化 cells 数组,没竞争时只用 base,省资源;有竞争才扩容(2 的幂次),并用 @Contended 注解隔离每个 Cell,防止伪共享——64 字节缓存行只放一个 value,避免不同 CPU 核心反复同步同一缓存行。这是典型的空间换时间策略,对服务端高频计数非常划算。


















