阿里推荐 LongAdder ,不推荐 AtomicLong !

其他系列文章导航

Java基础合集
数据结构与算法合集

设计模式合集

多线程合集

分布式合集

ES合集


文章目录

其他系列文章导航

文章目录

前言

一、CAS

1.1 CAS 全称

1.2 通俗理解CAS

1.3 CAS的问题

1.4 解决 ABA 问题

二、LongAdder

2.1 什么是 LongAdder

2.2 为什么推荐推荐 LongAdder

三、AtomicLong

3.1 什么是 AtomicLong 

3.2 为什么不推荐 AtomicLong

四、总结


前言

在分布式系统中,计数器是一个常见的需求。为了实现高并发、高可用的计数器,我们需要选择一个合适的实现方式。

在 Java 中,有两种常见的计数器实现方式:AtomicLong 和 LongAdder。

最近,阿里巴巴在一份技术报告中推荐使用 LongAdder ,而不是 AtomicLong 。

本文将介绍这两种计数器的原理和优缺点,并分析为什么阿里巴巴推荐使用 LongAdder 。


一、CAS

1.1 CAS 全称

全称:compare and swap,比较并交换。
虽然翻译过来是[比较并交换],但它是一个原子性的操作,对应到CPU指令为 cmpxchg 。

1.2 通俗理解CAS

  1. CAS 有三个操作数:当前值A、内存值V、要修改的新值B。
  2. 假设 当前值A 跟 内存值V 相等,那就将内存值V 改成B。
  3. 假设 当前值A 跟 内存值V 不相等,要么就重试,要么就放弃更新。
  4. 将当前值与内存值进行对比,判断是否有被修改过,这就是CAS的核心。

1.3 CAS的问题

CAS有个缺点就是会带来 ABA 的问题。
从CAS更新的时候,我们可以发现它只比对当前值和内存值是否相等,这会带来个问题,下面我举例说明下:

  1. 假设线程A读到当前值是10,可能线程B把值修改为100,然后线程C又把值修改为10。
  2. 等到线程A拿到执行权时,因为当前值和内存值是一致的,线程A是可以修改的!
  3. 站在线程A的角度来说,这个值是从未被修改的 。
  4. 这是不合理的,因为我们从上帝的角度来看,这个变量已经被线程B和线程C修改过了。

1.4 解决 ABA 问题

要解决ABA的问题,Java 也提供了 AtomicStampedReference 类供我们用,说白了就是加了个版本,比对的就是内存值+版本是否一致。

疑问:

为什么阿里巴巴开发手册提及到推荐使用 LongAdder 对象,比AtomicLong 性能更好(减少乐观锁的重试次数)?

原因:

因为 AtomicLong 做累加的时候实际上就是多个线程操作同一个目标资源。

在高并发时,只有一个线程是执行成功的,其他的线程都会失败,不断自旋(重试),自旋会成为瓶颈。

而 LongAdder 的思想就是把要操作的目标资源 分散,到数组 Cell 中。

每个线程对自己的 Cell 变量的 value 进行原子操作,大大降低了失败的次数。

这就是为什么在高并发场景下,推荐使用 LongAdder  的原因。


二、LongAdder

2.1 什么是 LongAdder

LongAdder是JDK1.8由Doug Lea大神新增的原子操作类,位于java.util.concurrent.atomic包下,LongAdder在高并发的场景下会比AtomicLong 具有更好的性能,代价是消耗更多的内存空间

LongAdder是Google开源的一个高性能计数器实现。它采用了一种分段锁的策略,将一个long型的变量分割成多个16字节的段,每个段都使用一个独立的AtomicLong进行更新。这样,在高并发场景下,多个线程可以同时对不同的段进行更新操作,互不干扰。

LongAdder的优点是并发性能高,适用于高并发的场景。由于采用了分段锁的策略,LongAdder可以避免AtomicLong中的竞争问题。此外,LongAdder还支持可扩展性,可以通过增加更多的段来提高性能。但是,LongAdder的缺点是代码相对复杂一些,需要更多的维护成本。

2.2 为什么推荐推荐 LongAdder

LongAdder设计思想上,采用分段的方式降低并发冲突的概率。通过维护一个基准值base和 Cell 数组

如下图所示:


三、AtomicLong

3.1 什么是 AtomicLong 

AtomicLong是Java提供的一个原子类,用于实现高并发的计数器。它利用了CAS(Compare-and-Swap)操作来保证线程安全。在AtomicLong中,每次计数操作都会先读取当前值,然后使用CAS操作更新值。如果值没有被其他线程修改过,则更新成功,否则需要重新尝试。

AtomicLong的优点是简单易用,性能也不错。但是,在高并发场景下,AtomicLong可能会出现竞争问题。因为多个线程可能同时读取和更新同一个AtomicLong的当前值,导致数据不一致。此外,AtomicLong的CAS操作也可能因为硬件和操作系统的原因出现失败的情况。

3.2 为什么不推荐 AtomicLong

在LongAdder之前,当我们在进行计数统计的时,通常会使用AtomicLong来实现。AtomicLong能保证并发情况下计数的准确性,其内部通过CAS来解决并发安全性的问题。

如下图所示:

图里可以看出在高并发情况下,当有大量线程同时去更新一个变量,任意一个时间点只有一个线程能够成功,绝大部分的线程在尝试更新失败后,会通过自旋的方式再次进行尝试,这样严重占用了CPU的时间片,进而导致系统性能问题。


四、总结

阿里巴巴推荐使用LongAdder的原因主要有以下几点:

  1. 高并发性能:LongAdder采用分段锁的策略,可以避免AtomicLong中的竞争问题,提高并发性能。在分布式系统中,高并发性能是非常重要的。
  2. 可扩展性:LongAdder支持可扩展性,可以通过增加更多的段来提高性能。这对于需要处理大量请求的分布式系统来说是非常有利的。
  3. 代码简单易懂:虽然LongAdder的代码相对复杂一些,但是相对于AtomicLong来说更容易理解和维护。这对于开发人员来说是非常重要的。
  4. 更好的适用场景:阿里巴巴推荐使用LongAdder主要是因为在分布式系统中需要一个高性能、高可用的计数器实现。而LongAdder正好符合这个需求。

总之,阿里巴巴推荐使用LongAdder的原因主要是因为它的高并发性能、可扩展性、代码简单易懂以及更好的适用场景。当然,在实际应用中还需要根据具体场景和需求进行选择和优化。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/260540.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

flutter自定义地图Marker完美展示图片

世人都说雪景美 寒风冻脚无人疼 只道是一身正气 结论 参考Flutter集成高德地图并添加自定义Maker先实现自定义Marker。如果自定义Marker中用到了图片,那么会碰到图片没有被绘制到Marker的问题,此时需要通过precacheImage来预加载图片,从而解…

Jenkins 构建环境指南

目录 Delete workspace before build starts(常用) Use secret text(s) or file(s) (常用) Add timestamps to the Console Output (常用) Inspect build log for published build scans Terminate a …

【分享】如何给Excel加密?码住这三种方法!

想要给Excel文件进行加密,方法有很多,今天分享三种Excel加密方法给大家。 打开密码 设置了打开密码的excel文件,打开文件就会提示输入密码才能打开excel文件,只有输入了正确的密码才能打开并且编辑文件,如果密码错误…

2023年度佳作:AIGC、AGI、GhatGPT 与人工智能大模型的创新与前景展望

🎬 鸽芷咕:个人主页 🔥 个人专栏:《linux深造日志》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! ⛳️ 写在前面参与规则 ✅参与方式:关注博主、点赞、收藏、评论,任意评论(每人最多评论…

Matlab-修改默认启动路径

Matlab-修改默认启动路径 第一:找到MATLAB的安装路径 第二步:进入到…\toolbox\local下,找到matlabrc.m 第三部:编辑matlabrc.m,在文本最后一行加入启动文件路径

ubuntu qt 源码编译

官方源码下载地址 : 源码地址 选择要下载的版本 dmg结尾的是MacOS系统里使用的Qt库,qt-everywhere-opensource-src-4.7.0是Qt源码包,有zip和tar.gz两个压缩格式的,两个内容是一样的,只是zip一般在Windows下比较流行,…

uniapp运行到手机模拟器

第一步,下载MUMU模拟器 下载地址:MuMu模拟器官网_安卓12模拟器_网易手游模拟器 (163.com) 第二步,运行mumu模拟器 第三步,运行mumu多开器 第三步,查看abs 端口 第四步,打开HBuilder,如下图,将…

Flink cdc3.0同步实例(动态变更表结构、分库分表同步)

文章目录 前言准备flink环境docker构建mysql、doris环境数据准备 通过 FlinkCDC cli 提交任务整库同步同步变更路由变更路由表结构不一致无法同步 结尾 前言 最近Flink CDC 3.0发布, 不仅提供基础的数据同步能力。schema 变更自动同步、整库同步、分库分表等增强功…

软考学习五部曲

视频学知识 学习知识环节看视频看书都可以,书很厚一本。如果要看完的话要很多时间,所以我觉得还是看视频更快一点,而且视频还可以倍速。我看的那个视频我觉得非常不错,但是我看的视频b站已经下架了看不到了。其他的视频没仔细去看…

数据库原理及应用·数据库系统结构

2.1 数据模型的概念 2.1.1 什么是数据模型 数据模型(Data Model) 是对现实世界数据特征的模拟和抽象,用来描述数据是如何组织、存储和操作的。 数据模型应满足如下三个条件: 能比较真实地模拟现实世界 容易为人所理解 便于在计…

MyBatis的ORM映射

目录 什么是ORM 一,列的别名 二,结果映射 三,总结 什么是ORM ORM:对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简…

图片抠图怎么抠?教你这几个方法抠图方法

图片抠图怎么抠?在数字化时代,图片抠图已经成为日常工作中不可或缺的一项任务。通过对图片的抠图处理,我们可以将图片中的某个元素提取出来,或者将图片背景更换,达到更好的视觉效果。那么图片抠图怎么抠?下…

基于ssm校园交友网站设计与实现(源码齐全可用)

项目描述 临近学期结束,还是毕业设计,你还在做java程序网络编程,期末作业,老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。你想解决的问题,今天给大家介绍…

YOLOv5改进 | 卷积篇 | 通过RFAConv重塑空间注意力(深度学习的前沿突破)

一、本文介绍 本文给大家带来的改进机制是RFAConv,全称为Receptive-Field Attention Convolution,是一种全新的空间注意力机制。与传统的空间注意力方法相比,RFAConv能够更有效地处理图像中的细节和复杂模式(适用于所有的检测对象都有一定的…

Kafka--Kafka日志索引详解以及生产常见问题分析与总结

一、Kafka的Log日志梳理 ​ 这一部分数据主要包含当前Broker节点的消息数据(在Kafka中称为Log日志)。这是一部分无状态的数据,也就是说每个Kafka的Broker节点都是以相同的逻辑运行。这种无状态的服务设计让Kafka集群能够比较容易的进行水平扩展。比如你需要用一个新…

猫目标检测数据集VOC+YOLO格式11000张

猫是一种非常受欢迎的宠物,它们有着柔软的毛发、敏捷的身体和灵活的尾巴。猫是一种非常独立的动物,也是一种非常聪明和好奇的动物。 猫是一种肉食性动物,主要以小型哺乳动物、鸟类和昆虫为食。它们通常在夜间活动,利用敏锐的听觉…

CodeBlocks配置WinLibs

一、准备工作 1、去Code::Blocks - Browse /Binaries/Nightlies at SourceForge.net下载CodeBlocks最新的nightly build版本,并下载wxWidget dll和Mingw64 dll库文件。 我下载的CB 13411 ,Mingw64dlls13.1.0.7z,wxmsw32u_gcc_cb_wx324_2D_g…

三大主流前端框架介绍及选型

在前端项目中,可以借助某些框架(如React、Vue、Angular等)来实现组件化开发,使代码更容易复用。此时,一个网页不再是由一个个独立的HTML、CSS和JavaScript文件组成,而是按照组件的思想将网页划分成一个个组…

mysql原理--连接的原理

1.连接简介 1.1.连接的本质 为了故事的顺利发展,我们先建立两个简单的表并给它们填充一点数据: mysql> CREATE TABLE t1 (m1 int, n1 char(1)); mysql> CREATE TABLE t2 (m2 int, n2 char(1)); mysql> INSERT INTO t1 VALUES(1, a), (2, b), (…

内衣洗衣机哪个牌子好用?十款小型洗衣机质量排名

最近这两年在洗衣机中火出圈的内衣洗衣机,它不仅可以清洁我们较难清洗的衣物,自带除菌功能,可以让衣物上的细菌,还能在清洗的过程中呵护我们衣物的面料,虽然说它是内衣洗衣机,它的功能不止可以清洗内衣&…