LongAccumulator是Java 8引入的高性能无锁并发累加器,基于分段累加(base+cells数组)和CAS机制实现高吞吐,支持自定义结合律二元函数(如sum/max/min)与单位元,适用于写多读少的统计聚合场景。

LongAccumulator 是 Java 8 引入的高性能并发累加器,专为高并发场景下替代 AtomicLong 或锁(如 synchronized)而设计。它通过“分段累加 + 最终合并”的策略,显著降低线程竞争,尤其适合写多读少、累加频率极高的场景(如计数器、指标统计、实时聚合等)。
核心原理:避免共享变量争用
不同于 AtomicLong 所有线程都竞争同一个 CAS 变量,LongAccumulator 内部维护一个 base 值和一个 cells 数组(类似 LongAdder 的结构)。每个线程优先尝试更新自己绑定的 cell;只有在发生竞争或 cell 未初始化时,才退回到 base 或扩容 cells。最终结果是 base 加上所有非空 cell 的值之和——这种“分散写、集中读”机制大幅减少了 CAS 失败率。
如何正确创建和使用 LongAccumulator
构造时需传入一个二元累加函数(如 Long::sum)和初始值。常见用法如下:
- 累加:调用
accumulate(x),线程安全,无返回值 - 获取当前总和:调用
get()(不重置),或sumThenReset()(获取并清零) - 设置新值:用
reset()清零,或accumulate(0)不推荐,应直接 reset
示例:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
LongAccumulator counter = new LongAccumulator(Long::sum, 0);counter.accumulate(1); // 线程安全累加
long total = counter.get(); // 获取当前总和
适用场景与关键注意事项
它不是万能替代品,使用前需确认是否匹配以下条件:
- ✅ 适用于纯累加类操作(支持任意结合律函数,如 sum/max/min/bitwise OR)
- ✅ 写远多于读,且对“实时一致性”要求不高(get() 是弱一致性快照)
- ❌ 不适合需要原子性读-改-写逻辑(如“如果小于100则加1”),此时仍需 AtomicLong 或显式锁
- ⚠️ 内存开销略高于 AtomicLong(cells 数组可能占用额外空间),但吞吐提升通常远超成本
对比 AtomicLong:什么时候选 LongAccumulator?
在压测中,当并发线程数 ≥ 4 且累加频次极高(如每毫秒数百次)时,LongAccumulator 吞吐量常比 AtomicLong 高 2–5 倍。简单判断标准:
- 仅做“不断加数字”,且不在乎某次 get() 是否严格滞后几个纳秒 → 选
LongAccumulator - 需要精确控制每次更新的条件、或依赖更新返回旧值 → 回退到
AtomicLong - 业务逻辑含复杂状态判断 → 考虑
ReentrantLock或更高级工具(如 StampedLock)
不复杂但容易忽略:初始化函数必须满足结合律和交换律(如 sum、max),否则结果不可预期。


















