Java并发工具:LongAccumulator

createh52周前 (05-13)技术教程3

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 用于浮点类型的累加操作。

适用场景

  • 并发环境中需要执行自定义的二元运算(如最大值、最小值、乘积等)
  • 高并发统计场景中需要灵活性更高的聚合逻辑

相关文章

1.3、Java运算符全解析

在Java编程语言中,**运算符(Operators)**是用于执行特定操作的符号。它们可以操作一个或多个操作数,并根据其功能返回结果。本文将详细介绍Java中的各种运算符及其使用方法。一、算术运算符...

Java并发工具:LongAdder

LongAdder 是 Java 中 java.util.concurrent.atomic 包下的一个类,从 Java 8 开始引入。它是一个可伸缩的并发累加器,适用于高并发场景下对长整型(long...

减法变加法的过程

5-1=4 变成加法分三步操作,取模、相加、去掉多余的位 1.取模:我们在这讨论的是十进制运算,那么模就是10,那么对-1取模就得到了9 2.相加: 5+9=14 3.去掉多余的位数:14去掉1=4...

Java BigDecimal类型的 加减乘除运算和比较

加法:add 减法:subtract 乘法:multiply 除法:divideBigDecimal bd1 = new BigDecimal("15"); BigDecimal bd...

总结一下Java中的运算符

对于Java来说,运算符有:算术运算符、比较运算符、赋值运算符、逻辑运算符、位运算符等。运算符是一种符号,当连接不同的操作数的时候,会实现特殊的功能。算术运算符Java中的算术运算符有:+:加法运算,...