-
Java高并发17-LongAccumulator类详解
一、LongAccumulator类
1.和LongAdder之间的关系
-
LongAdder类是LongAccumulator的一个特例,我们看一下LongAccumulator的一个构造方法
public LongAccumlator(LongBinaryOperator accumulatorFunction,long identity) {
this.function = accumulatorFunction;
base = this.identity = identity;
}
-
其中参数identity是累加器的初始值;参数类型LongBinaryOperator是一种相当于二目运算符的类,它的输入是两个Long型数,返回也是一个Long型数字,我们看一下这个接口定义
public interface LongBinaryOperator {
long applyAsLong(long left,long right);
}
-
下面来看一下两个类的等价形式
LongAdder adder = new LongAdder();
LongAccumulator accumulator = new LongAccumulator(new LongBinaryOperator() {
@Override
public long applyAsLong(long left,long right) {
return left + right;
}
}
-
LongAccumulator相比于LongAdder,可以为累加器提供非0的初始值,后者只能从0开始累加,并且前者可以自定义累加规则,我们只需要实现这个接口,然后在接口内部的方法内,自定累加规则即可。 -
从下面的代码看一下LongAccumulator的accumulate方法和LongAdder类的add方法
//LongAdder的add方法
public void add(long x){
Cell[] as;
long b;
long 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))){
longAccumulator(x,null,uncontended);
}
}
}
//LongAccumulator的accumulate方法
public void accumulate(long x){
Cell[] as;
long b;
long v;
int m;
Cell a;
if(as = cells) != null || r = function.applyAsLong(b = base,x))!= b && !casBase(b,r) {
boolean uncontended = true;
if(as == null || (m = as.length -1)<0 || (a = as[getProbe() & m]) == null || !(uncontended = (r = function.applyAsLong(v = a.value,x)) == v|| a.cas(v,r))){
longAccumulator(x,null,uncontended);
}
}
-
调用casBase的时候后者传递的是b+x,前者使用了r=function.applyAsLong(b = base,x)来计算 -
前者在调用longAccumulator时传递的是function,而后者是null,从下面的代码看出
else if(casBase(v = base,((fn==null)?v+x:fn.applyAsLong(v,x)))){
break;
}
-
当fu为null时,就是用了x+v的加法运算,这时候等价于LongAdder,当fn不为null则使用传递的fu函数计算
2.总结:可以看到该类提供的功能更加一般化
二、源码:
-
所在包:com.ruigege.AtomicOperationClass4 -
https://github.com/ruigege66/ConcurrentJava
-
CSDN:https://blog.csdn.net/weixin_44630050 -
博客园:https://www.cnblogs.com/ruigege0000/
出 处:https://www.cnblogs.com/ruigege0000/p/14249271.html
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
JavaScript判断两个数组相等的四类方法
js如何操作video标签
React实战--利用甘特图和看板,强化Paas平
【记录】正则替换的偏方
前端下载 Blob 类型整理
抽象语法树AST必知必会
关于JS定时器的整理
JS中使用Promise.all控制所有的异步请求都完
js中字符串的方法
import-local执行流程与node模块路径解析流程