LongAdder & AtomicInteger
JDK8 推荐 LongAdder替代 AtomicInteger,
AtomicInteger内部是实现使用 (网友使用jad反编译源码 参考 http://ifeve.com/enhanced-cas-in-jdk8/),高并发场景compareAndSwapInt 会不断的试错,有性能问题。
public final int getAndAddInt(Object obj, long l, int i) {
int j;
do
j = getIntVolatile(obj, l);
while(!compareAndSwapInt(obj, l, j, j + i));
return j;
} public native int getIntVolatile(Object obj, long l);
public final native boolean compareAndSwapInt(Object obj, long l, int i, int j);
LongAdder在AtomicLong的基础上将单点的更新压力分散到各个节点,在低并发的时候通过对base的直接更新可以很好的保障和AtomicLong的性能基本保持一致,而在高并发的时候通过分散提高了性能。
将待处理的数据,通过hash计算分散到Cell数组中分别处理,最后在汇总计算。
注意casBase ==> !casBase(b = base, b + x);表示CAS更新操作;如果一个线程去CAS失败,那么表示正在有一个线程正在CAS操作,表示竞争激烈;
// LongAdder
public void add(long x) {
Cell[] as; long b, v; int m; Cell a;
// !casBase(b = base, b + x);表示CAS更新操作;如果一个线程去CAS失败,那么表示正在有一个线程正在CAS操作,表示竞争激烈;
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);
}
}
LongAddr在高并发的时候,Cell数组的汇总计算会不准确, 在高并发获取全局唯一ID的时候,使用AtomicLong而不是LongAddr
参考
https://www.jianshu.com/p/67a75e36166f
https://www.cnblogs.com/gosaint/p/9129867.html
LongAdder & AtomicInteger的更多相关文章
- 对Java原子类AtomicInteger实现原理的一点总结
java原子类不多,包路径位于:java.util.concurrent.atomic,大致有如下的类: java.util.concurrent.atomic.AtomicBoolean java. ...
- [JDK8]性能优化之使用LongAdder替换AtomicLong
如果让你实现一个计数器,有点经验的同学可以很快的想到使用AtomicInteger或者AtomicLong进行简单的封装. 因为计数器操作涉及到内存的可见性和线程之间的竞争,而Atomic***的实现 ...
- Java原子类AtomicInteger实现原理的一点总结
java原子类不多,包路径位于:java.util.concurrent.atomic,大致有如下的类: java.util.concurrent.atomic.AtomicBoolean java. ...
- AtomicLong与LongAdder的区别
AtomicLong的原理 AtomicLong是通过依靠底层的CAS来保障原子性的更新数据,在要添加或者减少的时候,会使用死循环不断地cas到特定的值,从而达到更新数据的目的. LongAdder的 ...
- LongAdder类学习笔记
优秀原文 LongAdder | LongAccumulator简介 源码阅读:全方位讲解LongAdder 说到LongAdder,不得不提的就是AtomicLong.AtomicLong是JDK1 ...
- Java8 更快的原子类:LongAdder(笔记)
更快的原子类:LongAdder 大家对AtomicInteger的基本实现机制应该比较了解,它们是在一个死循环内,不断尝试修改目标值,知道修改成功,如果竞争不激烈,那么修改成功的概率就很高 ...
- AtomicInteger 源码分析
AtomicInteger AtomicInteger 能解决什么问题?什么时候使用 AtomicInteger? 支持原子更新的 int 值. 如何使用 AtomicInteger? 1)需要被多线 ...
- 一篇文章快速搞懂 Atomic(原子整数/CAS/ABA/原子引用/原子数组/LongAdder)
前言 相信大部分开发人员,或多或少都看过或写过并发编程的代码.并发关键字除了Synchronized,还有另一大分支Atomic.如果大家没听过没用过先看基础篇,如果听过用过,请滑至底部看进阶篇,深入 ...
- 并发编程——多线程计数的更优解:LongAdder原理分析
前言 最近在学习ConcurrentHashMap的源码,发现它采用了一种比较独特的方式对map中的元素数量进行统计,自然是要好好研究一下其原理思想,同时也能更好地理解ConcurrentHashMa ...
随机推荐
- CCD与CMOS的区别
我们在购买相机或是摄像机时,都会看到使用CMOS镜头或是CCD镜头,那么CCD与CMOS是什么意思呢,CCD与CMOS的区别是什么?首先,让我们了解CCD与CMOS的意思. CCDCCD使用一种高感光 ...
- ASP.NET Core的身份认证框架IdentityServer4--(5)自定义用户登录(通过接口登录,无UI版本)
官网接口详解文档地址:文档地址 (PS:可通过接口名称搜索相应接口信息.) 源码地址:https://github.com/YANGKANG01/IdentityServer4-IdentityAut ...
- UVA 1650 Number String
https://vjudge.net/problem/UVA-1650 题意:D表示比前一个数打,I表示比前一个数小,?表示不确定 给出一个长为n由D I?组成的字符串,问满足字符串大小要求的n+1的 ...
- 「七天自制PHP框架」应用:JSON生成器
刚刚开始学做一个WebAPP,数据查询的一般套路是通过一张PHP页面读取数据库,获得列表后“嵌写”在PHP页面中,虽然写法上丑陋至极,但也有“快糙猛”出效果的成就感,如图. 后来想想,不对啊,难道以后 ...
- 快速入门react
安装react npm install creat-react-app -g这里直接安装react的一个脚手架,里面包含了要用到的许多东西,帮助快速入门react 创建新项目 create-react ...
- jQuery.pin.js笔记
jQuery.pin.js是一个把元素钉在页面上某个位置的插件,它能够将某个元素一直挂在一个固定的位置而不论滚动条是否滚动. 特点: 1. 可以钉住一个元素,主要作用就是滚动超出的时候不会隐藏而是一直 ...
- C - K-inversions URAL - 1523 (dp + 线段树)
题目链接:https://cn.vjudge.net/contest/275079#problem/C 具体思路:我们可以分层的去建立,假设我们要找k层,我们可以先把满足1.2....k-1层的满足情 ...
- 深入理解Spring系列之八:常用的扩展接口
转载 https://mp.weixin.qq.com/s/XfhZltSlTall8wKwV_7fKg Spring不仅提供了一个进行快速开发的基础框架,而且还提供了很多可扩展的接口,用于满足一些额 ...
- 二. Jmeter--参数化
1. 新建一个txt文件,输入些数据, 一行有四个数据,用逗号分隔. 保存的时候Encoding选择Unicode 2.添加一个Thread Group, 然后添加一个CSV Data Set Con ...
- Petrozavodsk Summer Training Camp 2017 Day 9
Petrozavodsk Summer Training Camp 2017 Day 9 Problem A. Building 题目描述:给出一棵树,在树上取出一条简单路径,使得该路径的最长上升子序 ...