Java并发工具:LongAccumulator
LongAccumulator 是 Java 中
java.util.concurrent.atomic 包下的一个类,和 LongAdder 一样从 Java 8 引入。它是一个支持自定义累加函数的并发累加器,适用于高并发场景下对 long 类型值进行更灵活的操作。
基本概念
- LongAccumulator 允许你提供一个自定义的累加函数(LongBinaryOperator),用于定义两个操作数如何合并。
- 它内部也使用了类似分段锁的机制来提高并发性能。
- 与 LongAdder 不同的是,LongAdder 只能做加法操作,而 LongAccumulator 支持任意的二元运算(比如最大值、最小值、乘积等)。
构造方法
public LongAccumulator(LongBinaryOperator accumulatorFunction, long identity)
- accumulatorFunction:一个函数接口,表示每次累加时使用的操作。类型是 LongBinaryOperator,即 (currentValue, newValue) -> result
- identity:初始值
示例代码
示例1:求最大值
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.LongAccumulator;
import java.util.function.LongBinaryOperator;
public class LongAccumulatorExample {
public static void main(String[] args) throws InterruptedException {
// 使用 max 函数作为累加器
LongBinaryOperator maxOperator = (current, update) -> Math.max(current, update);
LongAccumulator accumulator = new LongAccumulator(maxOperator, Long.MIN_VALUE);
ExecutorService executor = Executors.newFixedThreadPool(4);
for (int i = 0; i < 10; i++) {
final long value = (i + 1) * 10;
executor.submit(() -> accumulator.accumulate(value));
}
executor.shutdown();
while (!executor.isTerminated()) {
}
System.out.println("Max Value: " + accumulator.get()); // 输出:100
}
}
示例2:求和(功能类似于 LongAdder)
// 求和操作
LongBinaryOperator sumOperator = (a, b) -> a + b;
LongAccumulator sumAccumulator = new LongAccumulator(sumOperator, 0);
sumAccumulator.accumulate(10);
sumAccumulator.accumulate(20);
System.out.println("Sum: " + sumAccumulator.get()); // 输出:30
示例3:求积
// 求积操作
LongBinaryOperator multiplyOperator = (a, b) -> a * b;
LongAccumulator productAccumulator = new LongAccumulator(multiplyOperator, 1);
productAccumulator.accumulate(2);
productAccumulator.accumulate(3);
productAccumulator.accumulate(4);
System.out.println("Product: " + productAccumulator.get()); // 输出:24
LongAccumulator vs LongAdder
特性 | LongAccumulator | LongAdder |
是否可自定义运算 | 是 | 否(只能加法) |
性能 | 略低于 LongAdder(因为函数调用开销) | 更快 |
适用场景 | 需要最大值、最小值、乘积等复杂运算 | 仅需要加减操作 |
初始值 | 可设置 | 固定为 0 |
注意事项
- get() 返回的是调用时刻的一个近似值,在并发修改时可能不是完全实时一致。
- 如果你不需要复杂的操作,只需要加法计数,推荐使用 LongAdder,它在性能上更有优势。
- 有对应的 DoubleAccumulator 用于浮点类型的累加操作。
适用场景
- 并发环境中需要执行自定义的二元运算(如最大值、最小值、乘积等)
- 高并发统计场景中需要灵活性更高的聚合逻辑