多线程教程(二十六)字段更新器、原子累加器

多线程系列(十六) -常用并发原子类详解 在 Java 的java.util.concurrent包中,除了提供底层锁、并发同步等工具类以外,还提供了一组原子操作类,大多以Atomic开头,他们位于java.util.concurrent.atomic包下。 阅读详情

多线程教程(二十六)字段更新器、原子累加器

一、字段更新器

常见的字段更新器:

  • AtomicReferenceFieldUpdater // 域 字段

  • AtomicIntegerFieldUpdater

  • AtomicLongFieldUpdater

利用字段更新器,可以针对对象的某个域(Field)进行原子操作,只能配合 volatile 修饰的字段使用,否则会出现异常

Exception in thread "main" java.lang.IllegalArgumentException: Must be volatile type

示例:

public class Test5 {
    private volatile int field;
    public static void main(String[] args) {
        AtomicIntegerFieldUpdater fieldUpdater =
            AtomicIntegerFieldUpdater.newUpdater(Test5.class, "field");
        Test5 test5 = new Test5();
        fieldUpdater.compareAndSet(test5, 0, 10);
        // 修改成功 field = 10
        System.out.println(test5.field);
        // 修改成功 field = 20
        fieldUpdater.compareAndSet(test5, 10, 20);
        System.out.println(test5.field);
        // 修改失败 field = 20
        fieldUpdater.compareAndSet(test5, 10, 30);
        System.out.println(test5.field);
    }
}

输出

10 
20 
20
二、原子累加器

原子累加器主要解决多线程情况下i++线程不安全的问题

1.累加器性能比较

private static <T> void demo(Supplier<T> adderSupplier, Consumer<T> action) {
    T adder = adderSupplier.get();
    long start = System.nanoTime();
    List<Thread> ts = new ArrayList<>();
    // 4 个线程,每人累加 50 万
    for (int i = 0; i < 40; i++) {
        ts.add(new Thread(() -> {
            for (int j = 0; j < 500000; j++) {
                action.accept(adder);
            }
        }));
    }
    ts.forEach(t -> t.start());
    ts.forEach(t -> {
        try {
            t.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    });
    long end = System.nanoTime();
    System.out.println(adder + " cost:" + (end - start)/1000_000);
}

比较 AtomicLong 与 LongAdder

for (int i = 0; i < 5; i++) {
    demo(() -> new LongAdder(), adder -> adder.increment());
}
for (int i = 0; i < 5; i++) {
    demo(() -> new AtomicLong(), adder -> adder.getAndIncrement());
}

输出

1000000 cost:43 
1000000 cost:9 
1000000 cost:7 
1000000 cost:7 
1000000 cost:7 
1000000 cost:31 
1000000 cost:27 
1000000 cost:28 
1000000 cost:24 
1000000 cost:22

性能提升的原因很简单,就是在有竞争时,设置多个累加单元,Therad-0 累加 Cell[0],而 Thread-1 累加Cell[1]… 最后将结果汇总。这样它们在累加时操作的不同的 Cell 变量,因此减少了 CAS 重试失败,从而提高性能。

LongAdder设计非常巧妙,有兴趣可以去看看他的代码和设计原理,这里就不做介绍了。后面会对其中最重要的伪共享进行介绍。

Java BigDecimal详解_动力节点Java学院整理 借用《Effactive Java》这本书中的话,float和double类型的主要设计目标是为了科学计算和工程计算。他们执行二进制浮点运算,这是为了在广域数值范围上提供较为精确的快速近似计算而精心设计的。然而,它们没有提供完全精确的结果,所以不应该被用于要求精确结果的场合。但是,商业计算往往要求结果精确,例如银行存款数额,这时候BigDecimal就派上大用场啦。 立即下载

相关推荐

避坑指南:Quectel EC200A-CN在OpenWrt或嵌入式Linux下的RNDIS/ECM网络配置全解析

本文详细解析了Quectel EC200A-CN模块在OpenWrt或嵌入式Linux下的RNDIS/ECM网络配置,包括模式选择、内核配置、动态切换AT指令、网络接口生成与排错、路由与防火墙设置、性能调优及特殊场景应对策略,帮助开发者避免常见配置陷阱,提升网络稳定性和效率。

weixin_42531588的博客 287

从InterruptedException深入理解AtomicReference的方方面面

本文从最初的开始详细分析了相关的方方面面,最终也将实际工作中遇到的问题加以解决。httpshttpshttpshttpshttps。

老男孩的架构路 620

Java8对接三方流式接口,并实时输出(GPT)

【代码】Java8对接三方流式接口,并实时输出(GPT)

m0_58617940的博客 1727

Java 比Automic更高效的累加器

与AtomicLong相比,DoubleAdder在高并发环境下能够提供更好的性能,因为它采用了分散(Striped)的设计,将内部的数据分为多个独立的单元进行累加,减少了竞争,从而提高了吞吐量。DoubleAccumulator也用于高效处理double类型的累加操作,不同的是它可以自定义累加的逻辑。compareAndSet 方法是 AtomicReference 类的原子操作方法,它会比较当前值是否与期望值相等,如果相等,则更新为新的值。如果当前值与期望值不相等,那么更新操作失败,线程需要重试。

FLGB 710

chmod: changing permissions of `/u01/app/oracle/product/11.2.0/dbhome_1/bin/extjobO‘: Operation not

oracle 11.2.0.4安装psu 29141056,日志末尾抛出报错 Patching component oracle.ctx, 11.2.0.4.0... Applying sub-patch '29141056' to OH '/u01/app/oracle/product/11.2.0/dbhome_1' Patching component oracle.rdbms, 11.2.0.4.0... Patching component oracle.rdbms.rman, 11.2.0.

m0_37625564的博客 1833

Camera | 瑞芯微rk3568平台MIPI-CSI驱动:从设备树到V4L2框架的完整链路解析

本文深入解析瑞芯微rk3568平台MIPI-CSI驱动的完整链路,从设备树配置到V4L2框架集成。详细介绍了rk3568的MIPI-CSI驱动架构、设备树关键节点布局、驱动初始化流程及数据流路径,帮助开发者快速掌握摄像头控制器的调试与优化技巧,实现稳定的视频采集系统。

weixin_28703489的博客 290

2.11Atomic

java原子类

weixin_43887682的博客 371

CLIP-Count代码配置以及踩坑记录

CLIP-Count代码配置以及踩坑记录

学术菜鸡 1011

【多线程十九】原子累加器&Unsafe

原子累加器、伪共享原理、Unsafe

Jennifer29的博客 530

结构优化软件:OptiStruct_(11).拓扑优化

在OptiStruct中,设计空间可以通过定义设计区域来实现。设计区域是结构中可以进行材料变化的部分。几何区域:通过几何选择工具选择特定的区域。网格区域:通过网格选择工具选择特定的单元。假设我们有一个简单的梁结构模型,网格文件为beam.fem。我们希望在梁的中部进行拓扑优化,以减轻重量并保持刚度。

kkchenjj的博客 1367

R语言单因素被试内ANOVA检验

在R语言中,我们可以使用多种方法进行被试内ANOVA检验,其中包括使用内建函数或使用外部包。我们随机选择了10个被试,并对每个被试使用了三种不同的药物处理。通过上述代码示例,我们可以使用R语言进行单因素被试内ANOVA检验。假设我们的数据存储在一个名为"data"的数据框中,其中包含两个列:一个列是被试的编号,另一个列是生物指标的测量值。在上述代码中,我们创建了一个名为"data"的数据框,其中"Subject"列包含了被试的编号,"Measurement"列包含了生物指标的测量值。参数指定了数据来源。

PixelNovaO的博客 363

Atomic原子类的使用及其原理

本文总结了常用的原子类,及其内部实现的原理--CAS原理。Java 提供的原子类能够解决一些简单的原子性问题,但你可能会发现,上面我们所有原子类的方法都是针对一个共享变量的,如果你需要解决多个变量的原子性问题,建议还是使用互斥锁方案。原子类虽好,但使用要慎之又慎。

Startapi的博客 1877

MIPI CSI-2

来源:公众号瓜大三哥版权归三哥所有1 MIPI简介2 MIPI CSI-2简介2.1 MIPI CSI-2 的层次结构2.2 CSI-2协议层2.3 打包/解包层2.4 ...

OpenFPGA的博客 2113

atomic原子类实现机制_多线程(五、原子类-AtomicReference)

AtomicReference 原子方式更新对象引用举例:1000个线程,对一个Integer累加1,直到1000启动文件package com.jane;import java.util.ArrayList;import java.util.List;import java.util.concurrent.atomic.AtomicReference;public class Main {pub...

weixin_33628144的博客 491

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Atomic 原子类详解

原理:LongAdder在内部维护一个数组,当多个线程尝试同时修改时,会分散到不同的数组中进行更新。在获取结果时,将所有数组的值相加得到总和。缺点:如果计算总和期间有线程修改,此次修改可能不会计入这次计算,所以不适合需要精确计算的场景。优点:减少并发修改时的CAS竞争,高并发场景下性能优于AtomicLong。:带标志引用型,可用于避免ABA问题。

化繁为简 489

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Java 原子性CAS 原理 ,atomic包 详解

java.util.concurrent.atomic包类的原理 atomic包底层原理都是Unsafe.compareAndSwapXXX()方法,也就是通常说的CAS,compareAndSwapXXX方法是native标识的方法,是Java底层代码,不是Java代码实现的, public final class Unsafe { //object public final native boolean compareAndSwapObject(Object obj, long offset,

坚定目标,超越自我 666

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

AtomicReference详解

AtomicReference详解

weixin_45428910的博客 3296

07.Atomic与Unsafe

Atomic与Unsafe 原子操作 原子操作介绍 原子(atom)本意是 不能被进一步分割的最小粒子 ,而原子操作(atomic operation) 意为 不可被中断的一个或一系列操作。 相关术语 术语名称 英文 解释 缓存行 Cache line 缓存的最小操作单位 比较并交换 Compare and Swap CAS操作需要输入两个数值,一个旧值(期望操作前的值)和一个新值,在操作期间先 生变化,如果没有发生变化,才交换成新值,发生了变化则不交换 CPU流水线 CPU pip

weixin_43891622的博客 423

多线程(五、原子类-AtomicReference)

AtomicReference 原子方式更新对象引用 举例:1000个线程,对一个Integer累加1,直到1000 启动文件 package com.jane; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicReference; public class ...

weixin_34329187的博客 426

原子操作类的正确使用实战

原子操作类提供了一种高效、线程安全的方式来操作共享变量,避免了传统锁机制的开销和复杂性。了解 CAS 原理:理解底层的 CAS 操作,有助于更好地使用原子操作类。选择合适的类:根据具体需求选择合适的原子操作类,如LongAdder等。注意 ABA 问题:在某些场景下,需要考虑 ABA 问题,可以使用来解决。性能考虑:在高并发场景下,使用LongAdder或可能比AtomicLong更合适。通过合理使用原子操作类,可以编写出高效且线程安全的并发程序。

qq_34358193的博客 669

Atomic详解

举个例子,比如说10个线程分别对data执行一次data++操作,我们以为最后data的值会变成10,其实不是。因为多线程并发操作下,就是会有这种安全问题,导致数据结果不准确。 public class Test { private int data=0; //多个线程对一个data不停的累加1操作 } 针对并发问题,可以加锁(比如内置锁或者lock),还有一种方式是使用Atomic相应的类和方法保证在并发下数据的准确性 一、Atomic AtomicInteger ,AtomicB...

勇心在馨 1193

【Java并发编程】AtomicReference 原子引用

概述: AtomicReference和AtomicInteger非常类似,不同之处就在于AtomicInteger是对整数的封装,底层采用的是compareAndSwapInt实现CAS,比较的是数值是否相等,而AtomicReference则对应普通的对象引用,底层使用的是compareAndSwapObject实现CAS,比较的是两个对象的地址是否相等。也就是它可以保证你在修改对象引用时的...

fxkcsdn的博客 2万+

高并发编程之AtomicReference讲解

一、AtomicReference介绍 ①.AtomicReference和AtomicInteger非常类似,不同之处就在于AtomicInteger是对整数的封装,而AtomicReference则对应普通的对象引用。也就是它可以保证你在修改对象引用时的线程安全性。 ②.AtomicReference是作用是对”对象”进行原子操作。 提供了一种读和写都是原子性的对象引用变量。原子意味着多个线程...

weixin_42146366的博客 5万+

AtomicInteger 累加方法实现原理(CAS应用解析)

/** * Atomically sets to the given value and returns the old value. * * @param newValue the new value * @return the previous value */ public final int getAndSet(in...

weixin_30628801的博客 644

并发编程 — 原子类 AtomicReference 详解

通过对 AtomicInteger、AtomicBoolean 和 AtomicLong 分析我们发现,这三个原子类只能对单个变量进行原子操作,那么我们如果要对多个变量进行原子操作,这三个类就无法实现了。那如果要进行多个变量进行原子操作呢?操作方式就是,先把 多个变量封装成一个类,然后通过 AtomicReference 进行操作。 众所周知,对象的引用其实是一个4字节的数字,代表着在JVM堆内存中的引用地址,对一个4字节数字的读取操作和写入操作本身就是原子性的,通常情况下,我们对对象引用的操作一般都是获

small_love的专栏 1万+
上一篇: 多线程教程(二十五)原子数组
下一篇: 多线程教程(二十七)cpu缓存、伪共享
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值