[JDK8]性能优化之使用LongAdder替换AtomicLong
如果让你实现一个计数器,有点经验的同学可以很快的想到使用AtomicInteger或者AtomicLong进行简单的封装。
因为计数器操作涉及到内存的可见性和线程之间的竞争,而Atomic***的实现完美的屏蔽了这些技术细节,我们只需要执行相应的方法,就能实现对应的业务需求。
Atomic**虽然好用,不过这些的操作在并发量很大的情况下,性能问题也会被相应的放大。我们可以先看下其中getAndIncrement
的实现代码
public final long getAndIncrement() {return unsafe.getAndAddLong(this, valueOffset, 1L); }// unsafe类中的实现 public final long getAndAddLong(Object var1, long var2, long var4) {long var6;do {var6 = this.getLongVolatile(var1, var2);} while(!this.compareAndSwapLong(var1, var2, var6, var6 + var4));return var6; }
很显然,在getAndAddLong
实现中,为了实现正确的累加操作,如果并发量很大的话,cpu会花费大量的时间在试错上面,相当于一个spin(自旋)的操作。如果并发量小的情况,这些消耗可以忽略不计。
既然已经意识到Atomic***有这样的业务缺陷,Doug Lea大神又给我们提供了LongAdder,内部的实现有点类似ConcurrentHashMap的分段锁,最好的情况下,每个线程都有独立的计数器,这样可以大量减少并发操作。
下面通过JMH比较一下AtomicLong 和 LongAdder的性能。
@OutputTimeUnit(TimeUnit.MICROSECONDS) @BenchmarkMode(Mode.Throughput) public class Main {private static AtomicLong count = new AtomicLong();private static LongAdder longAdder = new LongAdder();public static void main(String[] args) throws Exception {Options options = new OptionsBuilder().include(Main.class.getName()).forks(1).build();new Runner(options).run();}@Benchmark@Threads(10)public void run0(){count.getAndIncrement();}@Benchmark@Threads(10)public void run1(){longAdder.increment();} }
1、设置BenchmarkMode为Mode.Throughput,测试吞吐量
2、设置BenchmarkMode为Mode.AverageTime,测试平均耗时
线程数为1
1、吞吐量
Benchmark Mode Cnt Score Error Units Main.run0 thrpt 5 154.525 ± 9.767 ops/us Main.run1 thrpt 5 89.599 ± 7.951 ops/us
2、平均耗时
Benchmark Mode Cnt Score Error Units Main.run0 avgt 5 0.007 ± 0.001 us/op Main.run1 avgt 5 0.011 ± 0.001 us/op
单线程情况:
1、AtomicLong的吞吐量和平均耗时都占优势
线程数为10
1、吞吐量
Benchmark Mode Cnt Score Error Units Main.run0 thrpt 5 37.780 ± 1.891 ops/us Main.run1 thrpt 5 464.927 ± 143.207 ops/us
2、平均耗时
Benchmark Mode Cnt Score Error Units Main.run0 avgt 5 0.290 ± 0.038 us/op Main.run1 avgt 5 0.021 ± 0.001 us/op
并发线程为10个时:
- LongAdder的吞吐量比较大,是AtomicLong的10倍多。
- LongAdder的平均耗时是AtomicLong的十分之一。
线程数为30
1、吞吐量
Benchmark Mode Cnt Score Error Units Main.run0 thrpt 5 36.215 ± 2.341 ops/us Main.run1 thrpt 5 486.630 ± 26.894 ops/us
2、平均耗时
Benchmark Mode Cnt Score Error Units Main.run0 avgt 5 0.792 ± 0.021 us/op Main.run1 avgt 5 0.063 ± 0.002 us/op
线程数为30个时:
- LongAdder的吞吐量比较大,也是AtomicLong的10倍多。
- LongAdder的平均耗时也是AtomicLong的十分之一。
总结
一些高并发的场景,比如限流计数器,建议使用LongAdder替换AtomicLong,性能可以提升不少。
转载于:https://www.cnblogs.com/Joy-Hu/p/10715682.html
[JDK8]性能优化之使用LongAdder替换AtomicLong相关推荐
- 性能优化之使用LongAdder替换AtomicLong
欢迎关注方志朋的博客,回复"666"获面试宝典 来源:https://juejin.cn/post/6921595303460241415 写在前面 本篇文章并不会直接进入主题讲为 ...
- 拉勾教育 | Java 性能优化实战 21 讲
开篇词 开篇词 | Java 性能优化,是进阶高级架构师的炼金石 你好,我是李国.作为<Java 性能优化与面试 21 讲>这个课程的作者,我先来简单介绍下自己. 我曾任京东金融.陌陌科技 ...
- 《C++性能优化指南》 linux版代码及原理解读 第四章
目录 概述 为什么字符串很麻烦 字符串是动态分配的 字符串赋值背后的操作 如何面对字符串会进行大量复制 写时复制COW(copy on write) 尝试优化字符串 避免临时字符串 通过预留存储空间减 ...
- webpack学习:性能优化
本文内容如下 性能优化相关内容 如果你都有了答案,可以忽略本文章,或去webpack学习导图寻找更多答案 性能优化两大方面 一,开发环境性能优化 优化: 构建速度,代码调试 HMR热模块更新(代码调试 ...
- LongAdder和AtomicLong哪个性能更好,为什么?
点击关注公众号,实用技术文章及时了解 来源:blog.csdn.net/limenghua9112/ article/details/107950744 概述 AtomicLong是作者Doug Le ...
- 【078期】java.util.* 并发包下 LongAdder 和 AtomicLong 哪个性能更好,为什么?
点击上方"Java精选",选择"设为星标" 别问别人为什么,多问自己凭什么! 下方留言必回,有问必答! 每天 08:00 更新文章,每天进步一点点... 概述 ...
- 【Webpack 性能优化系列(1) - HMR 热模块替换】
webpack系列文章: [Webpack 性能优化系列(9) - 多进程打包]极大的提升项目打包构建速度!!! [Webpack 性能优化系列(8) - PWA]使用渐进式网络应用程序为我们的项目添 ...
- 性能优化常用工具及经验总结
文 |齐光 性能问题和 Bug 不同,后者的分析和解决思路更清晰,很多时候从应用日志(文中的应用指分布式服务下的单个节点)即可直接找到问题根源,而性能问题,其排查思路更为复杂一些. 对应用进行性能优化 ...
- 《Java性能调优实战》笔记(一)Java编程性能调优、多线程性能优化
文章目录 一.Java性能调优概述 1.1 性能调优标准 1.2 制定性能调优策略 二.Java编程性能调优 2.1 字符串 2.2 正则表达式 2.3 ArrayList和LinkedList的选择 ...
最新文章
- 什么是SESSION?(二)
- MyBatis学习总结(14)——Mybatis使用技巧总结
- 手把手构建LSTM的向前传播(Building a LSTM step by step)
- matlab循环矩阵
- 通过rsync清除目录的shell脚本
- 夏季防暑降温小常识汇总 - 生活至上,美容至尚!
- Redis 集合处理
- 《数据结构与算法分析-C语言描述》习题2.6
- 生成器案例,#采集日志
- [转]数据科学家能力发展路线图
- mysql 事务 不同库_MYSQL数据库重点:事务与锁机制
- mysql自动判断索引机制_Mysql优化之索引实现原理
- matlab求导函数作图,excel对数据求导作图/如何用excel计算导数
- Android关于网络访问app应用开发相关的异常总结
- 产品发布 | 全程托管、化繁为简,京东云上线API网关服务
- Expiring XXX record(s) for XXX:120015 ms has passed since batch creation
- 神经网络性能评价指标
- ol-ext transform 对象,旋转、拉伸、放大(等比例缩放),事件监听
- Swing学习笔记目录
- Xxl-Job 初次体验
热门文章
- session不是线程安全的
- APP压力測试新手教程
- C++11中正則表達式測试
- 设置修改CentOS系统时区
- 艰难万苦配置postfix+ldap+extmail+.......
- -9 逆序输出一个整数的各位数字_计算机基础知识: 信息数字化
- C 判断 —— if...else 语句(bool变量、float变量、指针变量与“零值”进行比较)(else 到底与哪个 if 配对呢? if 语句后面的分号?)
- 构造函数和析构函数的调用过程
- ReactNative生成android平台的bundle文件命令
- iOS WKWebView ios9以上版本配置 与 设置UserAgent(用户代理), 解决点击web, 客户端接收不到web事件问题...