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 源码分析的更多相关文章

  1. Java并发编程笔记之LongAdder和LongAccumulator源码探究

    一.LongAdder原理 LongAdder类是JDK1.8新增的一个原子性操作类.AtomicLong通过CAS算法提供了非阻塞的原子性操作,相比受用阻塞算法的同步器来说性能已经很好了,但是JDK ...

  2. ABP源码分析一:整体项目结构及目录

    ABP是一套非常优秀的web应用程序架构,适合用来搭建集中式架构的web应用程序. 整个Abp的Infrastructure是以Abp这个package为核心模块(core)+15个模块(module ...

  3. HashMap与TreeMap源码分析

    1. 引言     在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...

  4. nginx源码分析之网络初始化

    nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...

  5. zookeeper源码分析之五服务端(集群leader)处理请求流程

    leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...

  6. zookeeper源码分析之四服务端(单机)处理请求流程

    上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析 ...

  7. zookeeper源码分析之三客户端发送请求流程

    znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的 ...

  8. java使用websocket,并且获取HttpSession,源码分析

    转载请在页首注明作者与出处 http://www.cnblogs.com/zhuxiaojie/p/6238826.html 一:本文使用范围 此文不仅仅局限于spring boot,普通的sprin ...

  9. ABP源码分析二:ABP中配置的注册和初始化

    一般来说,ASP.NET Web应用程序的第一个执行的方法是Global.asax下定义的Start方法.执行这个方法前HttpApplication 实例必须存在,也就是说其构造函数的执行必然是完成 ...

随机推荐

  1. I-最短的名字

    在一个奇怪的村子中,很多人的名字都很长,比如aaaaa, bbb and abababab. 名字这么长,叫全名显然起来很不方便.所以村民之间一般只叫名字的前缀.比如叫’aaaaa’的时候可以只叫’a ...

  2. Spring如何读取xml配置文件的

    我们通过一个小案例来看xml解析过程. 1. 导包 <dependencies> <!-- xml解析工具 --> <dependency> <groupId ...

  3. 执行命令npm publish报错:403 Forbidden - PUT https://registry.npmjs.org/kunmomotest2 - You cannot publish over the previously published versions: 0.0.1.

    前言 执行命令npm publish报错:403 Forbidden - PUT https://registry.npmjs.org/kunmomotest2 - You cannot publis ...

  4. Out of memory: Kill process 25280 (php-fpm) score 86 or sacrifice child

    php-fpm 耗尽服务器内存的办法 java服务今天突然宕机,通过 cat /var/log/messages进行查看,发现是系统内存溢出导致系统把java的进程杀掉了 使用top查看系统内存使用情 ...

  5. Docker 启动与停止容器

    启动已运行过的容器 docker start 容器名称|容器id 如: docker start mycentos 启动所有运行过的容器(注意:反单引号` `), docker ps -a -q 是查 ...

  6. Selenium 2 & WebDriver &多线程 并发

    我用的是Selenium2,至于它的背景和历史就不赘述了.Selenium2也叫WebDriver.下面讲个例子,用WebDriver+java来写个自动化测试的程序.(如果能用firefox去测试的 ...

  7. Centos7.X新安装linux系统基础配置

    普通Linux分区方式: /根分区 Linux系统必须要有的,相当于 Windows的C盘,系统程序相关的. /boot分区 存放内核相关程序 是可选的 5 6给200M,7给256M(工作中1-2G ...

  8. bzoj2906 颜色 分块+块大小分析

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2906 题解 如果可以离线的话,那么这个题目就是一个莫队的裸题. 看上去这个数据范围也还会一个根 ...

  9. DevExpress ASP.NET Core Controls 2019发展蓝图(No.5)

    本文主要为大家介绍DevExpress ASP.NET Core Controls 2019年的官方发展蓝图,更多精彩内容欢迎持续收藏关注哦~ [DevExpress ASP.NET Controls ...

  10. 应用程序不了找到mysql中的表,客户端可以正常打开表

    原因是mysql中区分大小写的参数:lower-case-table-names=1  默认是区分大小写的,程序中代码可能是大小写混合的,其中访问数据库的sql是大小写混合的.所以找不到数据库中的表 ...