LongAdder在高并发下比AtomicLong更高效,因其采用分段累加+最终合并策略减少CAS自旋;适用于读多写少、只关心最终总和的监控场景,但sum()返回非原子快照,不保证强一致性。

LongAdder 在高并发场景下比 AtomicLong 更高效,核心在于它用“分段累加 + 最终合并”的策略减少线程间竞争,避免 CAS 自旋过度。它不是万能替代品,适用读多写少、只关心最终总和的计数场景(比如接口调用量、错误统计、性能指标汇总)。
什么时候该换用 LongAdder?
当你的计数器面临以下情况时,AtomicLong 可能成为瓶颈:
- 多个线程频繁调用
incrementAndGet()或add(),尤其在 4 核以上 CPU 或百线程级别并发时; - 监控类指标(如 QPS、失败次数),不需要实时强一致,允许短暂延迟或微小误差(LongAdder 的
sum()不是原子快照); - 压测中发现 AtomicLong 的 CAS 失败率明显上升,CPU 花费大量时间在自旋上。
怎么正确替换?关键三步
替换不只改类型,还要注意语义差异:
-
声明与初始化:用
new LongAdder()替代new AtomicLong(0); -
写操作保持一致:仍用
increment()、add(long x),语义和 AtomicLong 的对应方法相同; -
读操作必须改:不能用
get()(LongAdder 没有该方法),要用sum()获取当前估算值;若需强一致性读(极少见),得改用其他方案,LongAdder 本身不提供。
注意 LongAdder 的“非精确性”边界
sum() 返回的是一个近似值——它遍历内部 cell 数组并累加,过程中其他线程可能正在修改某些 cell,因此结果不保证是某一时刻的严格快照。但对大多数监控场景完全够用:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- 它不会丢失更新,所有
increment()都会被计入最终 sum; - 误差仅存在于“读取瞬间各 cell 值未完全同步”,通常偏差极小(纳秒级窗口);
- 如果业务逻辑依赖精确中间值(例如库存扣减、分布式锁序号),不要用 LongAdder,继续用 AtomicLong 或更严格的同步机制。
简单对比示例
旧写法(AtomicLong):
private final AtomicLong counter = new AtomicLong(); // 并发调用 counter.incrementAndGet(); // 高竞争下 CAS 自旋开销大 long current = counter.get(); // 强一致读
新写法(LongAdder):
private final LongAdder counter = new LongAdder(); // 并发调用(更轻量) counter.increment(); // 写入分散到不同 cell,冲突少 long current = counter.sum(); // 估算值,无强一致性保证


















