LongAccumulator 源码分析
LongAccumulator
LongAccumulator 能解决什么问题?什么时候使用 LongAccumulator?
1)LongAccumulator 的逻辑和 LongAdder 基本类似,唯一不同的是 LongAccumulator
持有一个函数式接口,目标值是通过该接口计算得到的,相对于 LongAdder,LongAccumulator 更灵活。
如何使用 LongAccumulator?
1)多线程并发更新一个统计值时可以采用 LongAccumulator,如最高同时在线人数。
使用 LongAccumulator 有什么风险?
1)LongAccumulator 使用空间换时间的模式会消耗更多的内存
LongAccumulator 核心操作的实现原理?
创建实例
/**
* 二元函数式接口
*/
private final LongBinaryOperator function;
/**
* 身份值
*/
private final long identity;
/**
* 基于一个二元函数式接口和身份值创建 LongAccumulator 实例
*/
public LongAccumulator(LongBinaryOperator accumulatorFunction,
long identity) {
function = accumulatorFunction;
base = this.identity = identity;
}
更新值
/**
* 使用指定的值 x 更新 LongAccumulator
*/
public void accumulate(long x) {
Cell[] cs; long b, v, r; int m; Cell c;
/**
* 1)cells 为 null &&
* 使用函数式接口基于 base 和目标值 x 计算新值不等于 b &&
* 尝试原子更新 base
* 2)cells 不为 null
*/
if ((cs = cells) != null
|| (r = function.applyAsLong(b = base, x)) != b
&& !casBase(b, r)) {
/**
* 1)原子更新失败
* 2)cells 不为 null
*/
boolean uncontended = true;
/**
* 1)cells 为 null,则执行初始化
* 2)通过线程探测值定位的 cell 为 null,则尝试直接写入值
* 3)基于 cell 值和目标值 x 计算后的值和旧值不相等 && 原子更新失败,
* 说明出现 cell 竞争,则需要重新计算并写入值。
*/
if (cs == null
|| (m = cs.length - 1) < 0
|| (c = cs[Striped64.getProbe() & m]) == null
|| !(uncontended =
(r = function.applyAsLong(v = c.value, x)) == v
|| c.cas(v, r))) {
longAccumulate(x, function, uncontended);
}
}
}
读取值
/**
* 根据函数式接口循环计算新值【参数为累计值和当前 Cell 中的旧值】并返回最终值,
* 如果计算过程中未发生竞争,则该值是精确的。
*/
public long get() {
final Cell[] cs = cells;
long result = base;
if (cs != null) {
for (final Cell c : cs) {
if (c != null) {
result = function.applyAsLong(result, c.value);
}
}
}
return result;
}
LongAccumulator 源码分析的更多相关文章
- Java并发编程笔记之LongAdder和LongAccumulator源码探究
一.LongAdder原理 LongAdder类是JDK1.8新增的一个原子性操作类.AtomicLong通过CAS算法提供了非阻塞的原子性操作,相比受用阻塞算法的同步器来说性能已经很好了,但是JDK ...
- ABP源码分析一:整体项目结构及目录
ABP是一套非常优秀的web应用程序架构,适合用来搭建集中式架构的web应用程序. 整个Abp的Infrastructure是以Abp这个package为核心模块(core)+15个模块(module ...
- HashMap与TreeMap源码分析
1. 引言 在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...
- nginx源码分析之网络初始化
nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...
- zookeeper源码分析之五服务端(集群leader)处理请求流程
leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...
- zookeeper源码分析之四服务端(单机)处理请求流程
上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析 ...
- zookeeper源码分析之三客户端发送请求流程
znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的 ...
- java使用websocket,并且获取HttpSession,源码分析
转载请在页首注明作者与出处 http://www.cnblogs.com/zhuxiaojie/p/6238826.html 一:本文使用范围 此文不仅仅局限于spring boot,普通的sprin ...
- ABP源码分析二:ABP中配置的注册和初始化
一般来说,ASP.NET Web应用程序的第一个执行的方法是Global.asax下定义的Start方法.执行这个方法前HttpApplication 实例必须存在,也就是说其构造函数的执行必然是完成 ...
随机推荐
- HNUSTOJ-1051 最长的波动序列
1051: 最长的波动序列 时间限制: 1 Sec 内存限制: 128 MB提交: 47 解决: 13[提交][状态][讨论版] 题目描述 有一个长度为N的整数序列,序列里面的数是两两不同的,现在 ...
- React事件绑定的几种方式对比
React事件绑定 由于类的方法默认不会绑定this,因此在调用的时候如果忘记绑定,this的值将会是undefined.通常如果不是直接调用,应该为方法绑定this.绑定方式有以下几种: 1. 在构 ...
- 学习Golang语言(6):类型--切片
学习Golang语言(1): Hello World 学习Golang语言(2): 变量 学习Golang语言(3):类型--布尔型和数值类型 学习Golang语言(4):类型--字符串 学习Gola ...
- 【论文解读】[目标检测]retinanet
作为单阶段网络,retinanet兼具速度和精度(精度是没问题,速度我持疑问),是非常耐用的一个检测器,现在很多单阶段检测器也是以retinanet为baseline,进行各种改进,足见retinan ...
- django字段类型(Field types)介绍
字段类型(Field types) AutoField 它是一个根据 ID 自增长的 IntegerField 字段.通常,你不必直接使用该字段.如果你没在别的字段上指定主 键,Django 就会自动 ...
- Response笔记
# 今日内容 1. HTTP协议:响应消息 2. Response对象 3. ServletContext对象 ## HTTP协议: 1. 请求消息:客户端发 ...
- 生成EXCEL文件是经常需要用到的功能,我们利用一些开源库可以很容易实现这个功能。
方法一:利用excellibrary,http://code.google.com/p/excellibrary/ excellibrary是国人写的开源组件,很容易使用,可惜貌似还不支持.xlsx( ...
- man - 格式化并显示在线帮助手册页
总览 man [-acdfFhkKtwW] [-m 系统名] [-p <前处理程序>] [-C <配置文件>] [-M <路径>] [-P <浏览方式> ...
- Codeforces Round #427 (Div. 2) - B
题目链接:http://codeforces.com/contest/835/problem/B 题意:给定一个数k和一个数字串n.问你最少改几个数字才能满足所有数字的和不小于k. 思路:考虑贪心,每 ...
- 64bit机器编译32bit汇编
sudo apt-get install gcc-multilib sudo apt-get install g++-multilib gcc -m32 -S a.c -o a.s gcc -m64 ...