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


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用JVS低代码实现业务流程的撤回和重新开始

在当今的数字化时代,业务流程的效率和准确性对于企业的运营至关重要。在实际业务场景中,我们可能需要处理一些复杂的流程,例如申请审批流程、合同签订流程等。这些流程在执行过程中可能会遇到各种情况,例如某个审批步骤需要重新审…

❀My虚拟机上的ftp服务器搭建(centos)❀

❀My虚拟机上的ftp服务器搭建(centos)❀ 在CentOS上搭建FTP服务器可以使用vsftpd软件,下面是详细的搭建教程: ①安装vsftpd软件 在终端中输入以下命令进行安装: sudo yum install vsftpd ②配置vsftpd 打开vsftpd的配置文件,…

【深度学习】序列生成模型(五):评价方法计算实例:计算BLEU-N得分【理论到程序】

文章目录 一、BLEU-N得分(Bilingual Evaluation Understudy)1. 定义2. 计算N1N2BLEU-N 得分 3. 程序 给定一个生成序列“The cat sat on the mat”和两个参考序列“The cat is on the mat”“The bird sat on the bush”分别计算BLEU-N和ROUGE-N得分(N1或…

WEB渗透—PHP反序列化(六)

Web渗透—PHP反序列化 课程学习分享(课程非本人制作,仅提供学习分享) 靶场下载地址:GitHub - mcc0624/php_ser_Class: php反序列化靶场课程,基于课程制作的靶场 课程地址:PHP反序列化漏洞学习_哔哩…

Ubuntu 22.04 禁用(彻底移除)Snap

什么是Snaps Snaps 是 Ubuntu 的母公司 Canonical 于 2016 年 4 月发布 Ubuntu 16.04 LTS(Long Term Support,长期支持版)时引入的一种容器化的软件包格式。自 Ubuntu 16.04 LTS 起,Ubuntu 操作系统可以同时支持 Snap 及 Debian …

3dsmax渲染太慢,用云渲染农场多少钱?

对于许多从事计算机图形设计的创作者来说,渲染速度慢是一个常见问题,尤其是对于那些追求极致出图效果的室内设计师和建筑可视化师,他们通常使用3ds Max这样的工具,而高质量的渲染经常意味着长时间的等待。场景复杂、细节丰富&…

APView500PV电能质量在线监测装置——安科瑞 顾烊宇

概述 APView500PV电能质量在线监测装置采用了高性能多核平台和嵌入式操作系统,遵照IEC61000-4-30《测试和测量技术-电能质量测量方法》中规定的各电能质量指标的测量方法进行测量,集谐波分析、波形采样、电压暂降/暂升/中断、闪变监测、电压不平衡度监测…

CentOS操作学习(二)

上一篇学习了CentOS的常用指令CentOS指令学习-CSDN博客 现在我们接着学习 一、Vi编辑器 这是CentOS中自带的编辑器 三种模式 进入编辑模式后 i:在光标所在字符前开始插入a:在光标所在字符串后开始插入o:在光标所在行的下面另起一新行插入…

命令执行 [SWPUCTF 2021 新生赛]easyrce

打开题目 提示要用url传参,但实际是用url进行一些系统命令执行 那我们就用whoami命令来查看用户和权限 那我们直接用ls / 去查看当下根目录下有哪些文件 我们看到根目录下有flag 直接cat读取就行 知识点: system system是一个函数 用来运行外部的程序…

4.CentOS7开启ssh

Centos7开启ssh 通过命令查看是否安装了ssh服务 rpm -qa | grep openssh 修改主配置文件 vim /etc/ssh/sshd_config 将PermitRootLogin,RSAAuthentication,PubkeyAuthentication的设置打开 RSAAuthentication yes# 启用 RSA 认证PubkeyAuthenticatio…

19_20-Golang中的切片

**Golang **中的切片 主讲教师:(大地) 合作网站:www.itying.com** **(IT 营) 我的专栏:https://www.itying.com/category-79-b0.html 1、为什么要使用切片 因为数组的长度是固定的并且数组长…

【.NET后端工具系列】MediatR实现进程内消息通讯

阅读本文你的收获 学习MediatR工具,实现进程内消息发送和处理过程的解耦学习MediatR的两种消息处理模式了解中介者模式和其好处 一、什么是MediatR? MediatR是一款基于中介者模式的思想而实现的.NET库,支持.NET Framework和跨平台 的.NET C…

aws配置以及下载 spaceNet6 数据集

一:注册亚马逊账号 注册的时候,唯一需要注意的是信用卡绑定,这个可以去淘宝买,搜索aws匿名卡。 注册完记得点击登录,记录一下自己的账户ID哦! 二:登录自己的aws账号 2.1 首先创建一个用户 首…

从YOLOv1到YOLOv8的YOLO系列最新综述【2023年4月】

作者:Juan R. Terven 、Diana M. Cordova-Esparaza 摘要:YOLO已经成为机器人、无人驾驶汽车和视频监控应用的核心实时物体检测系统。我们对YOLO的演变进行了全面的分析,研究了从最初的YOLO到YOLOv8每次迭代的创新和贡献。我们首先描述了标准…

研发管理-代码管理篇

前言: 工作了这些年,工作了三家公司,也用过主流的代码管理平台,比如SVN,git系列(gitlib,gitee),各有优点,我个人比较喜欢SVN,多人协作的代码管理难免会有代码冲突&#…

2024年【北京市安全员-B证】考试试卷及北京市安全员-B证复审模拟考试

题库来源:安全生产模拟考试一点通公众号小程序 北京市安全员-B证考试试卷根据新北京市安全员-B证考试大纲要求,安全生产模拟考试一点通将北京市安全员-B证模拟考试试题进行汇编,组成一套北京市安全员-B证全真模拟考试试题,学员可…

深入了解 npm 命令

目录 前言1 初始化项目2 安装依赖3 更新依赖4 发布包5 卸载包6 查看依赖7 运行脚本8 包搜索9 查看包信息结语 前言 在现代 Web 开发中,JavaScript 是一种至关重要的语言,而 npm(Node Package Manager)作为 Node.js 平台的默认软件…

ChatGPT如何计算token数?

GPT 不是适用于某一门语言的大型语言模型,它适用于几乎所有流行的自然语言。所以 GPT 的 token 需要 兼容 几乎人类的所有自然语言,那意味着 GPT 有一个非常全的 token 词汇表,它能表达出所有人类的自然语言。如何实现这个目的呢?…

SparkSQL读写数据

1.3 SparkSQL读写数据 1.3.1 数据的加载 Sparksql中加载外部的数据,使用统一的API入口, spark.read.format(数据文件格式).load(path) 这个方式有更加清晰的简写方式,比如要加载json格式的文件 spark.read.json(path) 默认加载的文件格式为…