当前位置: 首页 > news >正文

Java 比Automic更高效的累加器

1、 java常见的原子类

类 Atomiclnteger、AtomicIntegerArray、AtomicIntegerFieldUpdater、AtomicLongArray、 AtomicLongFieldUpdater、AtomicReference、AtomicReferenceArray 和 AtomicReference- FieldUpdater

常见的原子类使用方法

使用 AtomicReference 来创建一个原子的 Double 引用 atomicDouble,初始值为 0.0。然后,多个线程并发执行累加操作,在每个线程内部使用 compareAndSet 方法来原子地更新累加结果。

compareAndSet 方法是 AtomicReference 类的原子操作方法,它会比较当前值是否与期望值相等,如果相等,则更新为新的值。如果当前值与期望值不相等,那么更新操作失败,线程需要重试。

请注意,使用 AtomicReference 只是一种手段,实现了类似原子操作的效果。由于 Double 是一个包装类型,操作它的时候需要注意自动装箱和拆箱的性能开销。如果需要高性能的原子 double 操作,可以考虑使用类似 DoubleAdder 的高性能原子类。

代码:

import java.util.concurrent.atomic.AtomicReference;public class AtomicDoubleExample {public static void main(String[] args) throws InterruptedException {AtomicReference<Double> atomicDouble = new AtomicReference<>(0.0);// 多个线程并发执行累加操作for (int i = 1; i <= 10; i++) {final double valueToAdd = i * 1.0; // 值为 1.0, 2.0, 3.0, ..., 10.0new Thread(() -> {while (true) {Double oldValue = atomicDouble.get();Double newValue = oldValue + valueToAdd;if (atomicDouble.compareAndSet(oldValue, newValue)) {// 成功更新后退出循环break;}}}).start();}// 主线程等待所有累加线程执行完成Thread.sleep(1000);// 打印累加结果System.out.println("Accumulated Result: " + atomicDouble.get());}
}

2、更高效的累加器Adder、Accumulator

例如:DoubleAdder和DoubleAccumulator也是用来处理double类型的值,并且在处理方式上与LongAdder和LongAccumulator类似

DoubleAdder

DoubleAdder是用于高效处理double类型累加操作的类。与AtomicLong相比,DoubleAdder在高并发环境下能够提供更好的性能,因为它采用了分散(Striped)的设计,将内部的数据分为多个独立的单元进行累加,减少了竞争,从而提高了吞吐量。

DoubleAdder的常用方法包括:

add(double x): 将指定的double值加到当前总和。
sum(): 返回当前的总和值。

示例代码:


public class CustomDoubleAdder {public static void main(String[] args) throws InterruptedException {DoubleAdder doubleAdder = new DoubleAdder();// 多个线程并发执行累加操作
for (int i = 0; i < 10; i++) {new Thread(() -> {doubleAdder.add(1.0);}).start();
}// 主线程等待所有累加线程执行完成
Thread.sleep(1000);System.out.println("Sum: " + doubleAdder.sum());}
}

DoubleAccumulator

DoubleAccumulator也用于高效处理double类型的累加操作,不同的是它可以自定义累加的逻辑。DoubleAccumulator使用DoubleBinaryOperator函数接口来定义累加操作的逻辑。

DoubleAccumulator的常用方法包括:

accumulate(double x): 使用自定义的累加函数将指定的double值加到当前累加结果。
get(): 返回当前的累加结果。

示例代码:
使用 DoubleBinaryOperator 函数接口来定义自定义的累加逻辑。DoubleBinaryOperator 是一个函数接口,它接受两个 double 类型的参数,并返回一个 double 类型的结果。使用 lambda 表达式或实现该接口来定义累加逻辑。

构造 DoubleAccumulator 时,需要传递一个初始值和一个 DoubleBinaryOperator 对象。初始值是累加的起始值,而 DoubleBinaryOperator 对象定义了每次累加时的操作逻辑。

import java.util.concurrent.atomic.DoubleAccumulator;
import java.util.function.DoubleBinaryOperator;public class CustomDoubleAccumulator {public static void main(String[] args) throws InterruptedException {// 定义自定义的累加逻辑,这里使用乘法进行累加DoubleBinaryOperator customAccumulator = (x, y) -> x * y;// 初始值为1.0double initialValue = 1.0;DoubleAccumulator doubleAccumulator = new DoubleAccumulator(customAccumulator, initialValue);// 多个线程并发执行累加操作for (int i = 1; i <= 10; i++) {final double valueToAdd = i * 1.0; // 值为 1.0, 2.0, 3.0, ..., 10.0new Thread(() -> {doubleAccumulator.accumulate(valueToAdd);}).start();}// 主线程等待所有累加线程执行完成Thread.sleep(1000);// 打印累加结果System.out.println("Accumulated Result: " + doubleAccumulator.get());}
}
http://www.lryc.cn/news/109431.html

相关文章:

  • antDv table组件滚动截图方法的实现
  • JavaSE【抽象类和接口】(抽象类、接口、实现多个接口、接口的继承)
  • 微信小程序如何跳转H5页面
  • C++(20):bit_cast
  • STM32 低功耗-停止模式
  • Hutool中 常用的工具类和方法
  • K8s(健康检查+滚动更新+优雅停机+弹性伸缩+Prometheus监控+配置分离)
  • Django学习记录:使用ORM操作MySQL数据库并完成数据的增删改查
  • React Hooks 中的 useEffect(副作用)
  • [CKA]考试之持久化存储卷PersistentVolume
  • 基于LLM的SQL应用程序开发实战(一)
  • 如何批量实现多行合并后居中
  • 【深度学习_TensorFlow】手写数字识别
  • antv/l7地图,鼠标滚动,页面正常滑动-- 我们忽略的deltaY
  • 再续AM335x经典,米尔TI AM62x核心板上市,赋能新一代HMI
  • springboot和Django哪一个做web服务器框架更好
  • C#核心知识回顾——21.归并排序
  • 基于netty的rpc远程调用
  • RabbitMQ输出日志配置
  • 解决一个Sqoop抽数慢的问题,yarn的ATSv2嵌入式HBASE崩溃引起
  • 为Android构建现代应用——应用导航设计
  • 聊聊 Docker 和 Dockerfile
  • element表格+表单+表单验证结合u
  • 数据库:MYSQL参数max_allowed_packet 介绍
  • 基于DiscordMidjourney API接口实现文生图
  • springboot+vue农产品特产商城销售平台_50kf2 多商家
  • 【深度学习_TensorFlow】感知机、全连接层、神经网络
  • 软件测试(功能、接口、性能、自动化)详解
  • Oracle表段中的高水位线HWM
  • 【福建事业单位-推理判断】03类别推理