LongAccumulator是Java 8引入的高并发自定义累加器,基于CAS与分段Cell机制实现,支持任意结合律二元运算,性能优于AtomicLong;通过base值与动态扩容的Cell数组分担竞争,sum()返回总和,适用于最终一致性统计场景。

LongAccumulator 是 Java 8 引入的并发工具类,专为高并发场景下的自定义累加设计,底层基于 Unsafe 的 CAS 操作 + 分段累加(cell 分片)机制,避免多线程竞争同一变量,比 AtomicLong 在高争用下性能更好。
核心原理:分段累加 + 动态扩容
它不只维护一个共享值,而是维护一个 base 值和一组 Cell 数组(类似 LongAdder 的 cells)。线程先尝试 CAS 更新 base;失败则哈希定位到自己的 Cell 进行局部更新;Cell 不存在或冲突时会扩容。最终 sum() 返回 base + 所有非空 Cell 的值之和。
关键点:
- 每个线程尽量操作自己专属的 Cell,大幅减少 CAS 冲突
- Cell 数组大小是 2 的幂,通过线程 probe 值哈希定位,避免伪共享(JDK 9+ 默认启用缓存行填充)
- 累加逻辑由用户传入的
LongBinaryOperator定义,支持任意二元运算(如 +、^、min、max、gcd 等)
如何创建并使用自定义累加器
构造函数需指定一个二元操作函数和初始值:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
// 累加求和(等价于 LongAdder) LongAccumulator sum = new LongAccumulator(Long::sum, 0); // 求最大值 LongAccumulator max = new LongAccumulator(Math::max, Long.MIN_VALUE); // 异或累积(常用于校验或哈希合并) LongAccumulator xor = new LongAccumulator((x, y) -> x ^ y, 0); // 最小值(注意初始值设为 Long.MAX_VALUE) LongAccumulator min = new LongAccumulator(Math::min, Long.MAX_VALUE);
调用 accumulate(x) 执行一次累加,get() 或 sum() 获取当前结果。
注意事项与最佳实践
使用时需注意以下细节:
- 操作必须满足结合律(如 +、&、|、^、max、min),否则并发累加结果可能不一致(虽然实际多数场景仍可用,但语义不严格保证)
- 初始值应是该运算的“单位元”:求和用 0、乘积用 1、max 用 MIN_VALUE、min 用 MAX_VALUE、异或用 0
- 不支持获取中间过程的精确瞬时值(因各 Cell 异步更新),适合“最终一致性”统计场景,不适合强实时校验
- 内存开销略高于 AtomicLong(尤其 cell 数组较大时),但吞吐优势在高并发(如 >4 核、大量线程频繁更新)下非常明显
对比 LongAdder 和自定义累加器
LongAdder 是 LongAccumulator 的特例(仅支持加法),内部直接 hardcode 了加法逻辑;而 LongAccumulator 更通用,允许任意二元函数。若只需求和,用 LongAdder 语义更清晰;若需 max/min/xor/自定义聚合,必须用 LongAccumulator。
两者共享同一套分段 CAS 实现,性能特征几乎一致。

















