LongBinaryOperator是定义累加逻辑的纯函数接口,不提供并发控制;其applyAsLong方法描述两long值合并规则,由LongAccumulator等底层无锁机制保障线程安全。

LongBinaryOperator 本身不是锁,也不提供并发控制能力,它只是定义“如何把两个 long 值合并”的函数接口。在并发计数器中,它的作用是**描述累加逻辑**,而真正保障线程安全的是底层封装类(如 LongAccumulator 或 LongAdder)的无锁机制。
LongBinaryOperator 是累加规则的“说明书”
它只有一个抽象方法:applyAsLong(long left, long right),其中:
- left 是当前已累积的值(可能来自 base、某个 Cell,或上一次成功更新后的快照)
-
right 是本次要“加入”的操作数(比如
accumulate(5)中的 5) - 返回值就是两者按业务规则合并后的结果(常见为
left + right,也可是Math.max(left, right)等)
这个函数必须是无副作用、纯函数——因为底层可能因 CAS 失败而多次重试调用它,若含状态修改或 IO,会导致不可预知行为。
它在 LongAccumulator 中驱动原子更新
LongAccumulator 将 LongBinaryOperator 与初始值(identity)一起封装,内部使用类似 LongAdder 的分段 Cell 数组 + base 变量结构。每次 accumulate(x) 调用时:
立即学习“Java免费学习笔记(深入)”;
- 先尝试对 base 执行 CAS:用
function.applyAsLong(base, x)计算期望值,再 CAS 更新 - 若失败(说明有竞争),则定位到某个 Cell 槽位,对该 Cell.value 执行同样逻辑的 CAS
- Cell 不存在或扩容时,会通过自旋锁(
cellsBusy)协调创建
整个过程不依赖 synchronized 或 ReentrantLock,而是靠 CAS + 函数式计算 + 分散写入实现高并发吞吐。
和 LongAdder 的关键区别:灵活性 vs 专用性
LongAdder 固定只做加法(base += delta),而 LongAccumulator 把“加什么、怎么加”完全交给 LongBinaryOperator:
- 求和:
(a,b) -> a + b(等价于 LongAdder) - 求最大值:
(a,b) -> Math.max(a,b),identity 设为Long.MIN_VALUE - 求最小值:
(a,b) -> Math.min(a,b),identity 设为Long.MAX_VALUE - 按位或:
(a,b) -> a | b,适合标志位聚合
这种设计让同一套底层并发结构可适配多种聚合语义,避免为每种运算单独造轮子。
实际使用注意点
直接用 LongBinaryOperator 不保证线程安全;必须配合 LongAccumulator(或 DoubleAccumulator)才能生效:
- 不要自己在线程间共享并调用它——它只是个函数,不是容器
- reset() 和 getThenReset() 在并发更新时行为不确定,仅适用于明确无竞争的检查点场景
- get() 返回的是近似实时值,不是强一致快照;如需精确瞬时值,仍应回归 AtomicLong
- 内存开销比 AtomicLong 明显更高,Cell 数组在高争用下会动态扩容


















