Java并发编程之LongAdder源码分析

2023-05-30 0 5,049

前言

根据源码来分析一下它的基本实现流程

This class is usually preferable to AtomicLong when multiple threads update a common sum that is used for purposes such as collecting statistics, not for fine-grained synchronization control. Under low update contention, the two classes have similar characteristics. But under high contention, expected throughput of this class is significantly higher, at the expense of higher space consumption.

上面这段话是LongAdder源码注释中的一部分,翻译过来意思大概是

当多个线程更新用于收集统计信息但不用于细粒度同步控制的目的的公共和时,此类通常优于AtomicLong。 在低更新争用下,这两个类具有相似的特征。 但在高争用的情况下,这一类的预期吞吐量明显更高,但代价是空间消耗更高。

也就是说LongAdder在并发度高的情况下效率更高,但是代价是以空间换时间。

通俗地解释一下LongAdder的原理:当并发少的时候,累加操作只在一个变量base上执行就够用了,所以和AtomicLong类似;但是当并发量上来的时候,如果还是在变量base上进行操作就会有很多线程阻塞,所以就创建一个数组cells,在数组的每一个元素上都可以进行累加,最后计算结果时再就算一下basecells数组每个元素的和就行了。而线程具体在数组的哪一位进行操作可以通过计算hash来确定索引位置。

源码简介

LongAdder从父类Striped64继承过来的属性,这里的Cell是一个用来进行累加操作的内部类,内部有一个value属性来存储累加的值。

// CPU核心数
static final int NCPU = Runtime.getRuntime().availableProcessors();
// 并发高时进行累加的Cell数组
transient volatile Cell[] cells;
// 多个线程没有竞争时在base上进行累加
transient volatile long base;
// Cell数组是否正在创建或扩容
transient volatile int cellsBusy;

累加操作方法increment()实际调用的是add(1L),所以我们直接来看add方法

public void add(long x) {
    Cell[] as; long b, v; int m; Cell a;
    if ((as = cells) != null || !casBase(b = base, b + x)) {
        boolean uncontended = true; // 表示没有竞争
        if (as == null || (m = as.length - 1) < 0 ||
            (a = as[getProbe() & m]) == null ||
            !(uncontended = a.cas(v = a.value, v + x)))
            longAccumulate(x, null, uncontended);
    }
}

首先来看第一个if语句,初始状况下cellsnull,所以会进行casBase操作,也就是在base变量上进行累加,如果操作成功了说明当前没有竞争,所以就结束了。

当并发量上来的时候,进行casBase方法就有可能会失败,所以这时进入第二个if语句判断。

  • 第一次进来时Cell数组asnull,所以就会执行longAccumulate,对Cell数组as进行初始化并且在索引1位置累加1

  • 之后再执行到这个if语句as就不是null了,而且数组长度也大于0

  • a = as[getProbe() & m]) == null,这句话简单的理解就是在数组as中随机找到一个索引位置,判断该位置的值是不是null,如果是null的话就执行longAccumulate,不是null继续向下判断

  • !(uncontended = a.cas(v = a.value, v + x))这句话的意思是,在找到的这个索引位置进行累加操作,如果成功了就结束操作,如果失败了就执行longAccumulate

资源下载此资源下载价格为1小猪币,终身VIP免费,请先
由于本站资源来源于互联网,以研究交流为目的,所有仅供大家参考、学习,不存在任何商业目的与商业用途,如资源存在BUG以及其他任何问题,请自行解决,本站不提供技术服务! 由于资源为虚拟可复制性,下载后不予退积分和退款,谢谢您的支持!如遇到失效或错误的下载链接请联系客服QQ:442469558

:本文采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可, 转载请附上原文出处链接。
1、本站提供的源码不保证资源的完整性以及安全性,不附带任何技术服务!
2、本站提供的模板、软件工具等其他资源,均不包含技术服务,请大家谅解!
3、本站提供的资源仅供下载者参考学习,请勿用于任何商业用途,请24小时内删除!
4、如需商用,请购买正版,由于未及时购买正版发生的侵权行为,与本站无关。
5、本站部分资源存放于百度网盘或其他网盘中,请提前注册好百度网盘账号,下载安装百度网盘客户端或其他网盘客户端进行下载;
6、本站部分资源文件是经压缩后的,请下载后安装解压软件,推荐使用WinRAR和7-Zip解压软件。
7、如果本站提供的资源侵犯到了您的权益,请邮件联系: 442469558@qq.com 进行处理!

猪小侠源码-最新源码下载平台 Java教程 Java并发编程之LongAdder源码分析 http://www.20zxx.cn/763132/xuexijiaocheng/javajc.html

猪小侠源码,优质资源分享网

常见问题
  • 本站所有资源版权均属于原作者所有,均只能用于参考学习,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担
查看详情
  • 最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,建议提前注册好百度网盘账号,使用百度网盘客户端下载
查看详情

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务