Java CAS原理

【JAVA】原子类AtomicInteger与CAS原理(35) 摘要:本文介绍了Java原子类AtomicInteger及其CAS原理。AtomicInteger通过原子操作实现线程安全的整数运算,避免了同步锁的开销,适合计数器等场景(如网站访问统计)。CAS(比较并交换)是一种无锁并发机制,通过比较内存值与预期值实现原子更新,但存在ABA问题。文章通过代码示例展示了AtomicInteger在多线程任务调度和分布式锁中的应用,并对比了其与普通int的差异,同时提供了CAS的优化建议(如使用版本号解决ABA问题)。 阅读详情

1、什么是CAS?

CAS:Compare and Swap,即比较再交换。

jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronouse同步锁的一种乐观锁。JDK 5之前Java语言是靠synchronized关键字保证同步的,这是一种独占锁,也是是悲观锁。

2、CAS算法理解

对CAS的理解,CAS是一种无锁算法,CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。

CAS比较与交换的伪代码可以表示为:

do{

备份旧数据;

基于旧数据构造新数据;

}while(!CAS( 内存地址,备份的旧数据,新数据 ))

在这里插入图片描述

注:t1,t2线程是同时更新同一变量56的值

因为t1和t2线程都同时去访问同一变量56,所以他们会把主内存的值完全拷贝一份到自己的工作内存空间,所以t1和t2线程的预期值都为56。

假设t1在与t2线程竞争中线程t1能去更新变量的值,而其他线程都失败。(失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次发起尝试)。t1线程去更新变量值改为57,然后写到内存中。此时对于t2来说,内存值变为了57,与预期值56不一致,就操作失败了(想改的值不再是原来的值)。

(上图通俗的解释是:CPU去更新一个值,但如果想改的值不再是原来的值,操作就失败,因为很明显,有其它操作先改变了这个值。)

就是指当两者进行比较时,如果相等,则证明共享数据没有被修改,替换成新值,然后继续往下运行;如果不相等,说明共享数据已经被修改,放弃已经所做的操作,然后重新执行刚才的操作。容易看出 CAS 操作是基于共享数据不会被修改的假设,采用了类似于数据库的commit-retry 的模式。当同步冲突出现的机会很少时,这种假设能带来较大的性能提升。

3、CAS开销

前面说过了,CAS(比较并交换)是CPU指令级的操作,只有一步原子操作,所以非常快。而且CAS避免了请求操作系统来裁定锁的问题,不用麻烦操作系统,直接在CPU内部就搞定了。但CAS就没有开销了吗?不!有cache miss的情况。这个问题比较复杂,首先需要了解CPU的硬件体系结构:

在这里插入图片描述

上图可以看到一个8核CPU计算机系统,每个CPU有cache(CPU内部的高速缓存,寄存器),管芯内还带有一个互联模块,使管芯内的两个核可以互相通信。在图中央的系统互联模块可以让四个管芯相互通信,并且将管芯与主存连接起来。数据以“缓存线”为单位在系统中传输,“缓存线”对应于内存中一个 2 的幂大小的字节块,大小通常为 32 到 256 字节之间。当 CPU 从内存中读取一个变量到它的寄存器中时,必须首先将包含了该变量的缓存线读取到 CPU 高速缓存。同样地,CPU 将寄存器中的一个值存储到内存时,不仅必须将包含了该值的缓存线读到 CPU 高速缓存,还必须确保没有其他 CPU 拥有该缓存线的拷贝。

比如,如果 CPU0 在对一个变量执行“比较并交换”(CAS)操作,而该变量所在的缓存线在 CPU7 的高速缓存中,就会发生以下经过简化的事件序列:

CPU0 检查本地高速缓存,没有找到缓存线。

请求被转发到 CPU0 和 CPU1 的互联模块,检查 CPU1 的本地高速缓存,没有找到缓存线。

请求被转发到系统互联模块,检查其他三个管芯,得知缓存线被 CPU6和 CPU7 所在的管芯持有。

请求被转发到 CPU6 和 CPU7 的互联模块,检查这两个 CPU 的高速缓存,在 CPU7 的高速缓存中找到缓存线。

CPU7 将缓存线发送给所属的互联模块,并且刷新自己高速缓存中的缓存线。

CPU6 和 CPU7 的互联模块将缓存线发送给系统互联模块。

系统互联模块将缓存线发送给 CPU0 和 CPU1 的互联模块。

CPU0 和 CPU1 的互联模块将缓存线发送给 CPU0 的高速缓存。

CPU0 现在可以对高速缓存中的变量执行 CAS 操作了

以上是刷新不同CPU缓存的开销。最好情况下的 CAS 操作消耗大概 40 纳秒,超过 60 个时钟周期。这里的“最好情况”是指对某一个变量执行 CAS 操作的 CPU 正好是最后一个操作该变量的CPU,所以对应的缓存线已经在 CPU 的高速缓存中了,类似地,最好情况下的锁操作(一个“round trip 对”包括获取锁和随后的释放锁)消耗超过 60 纳秒,超过 100 个时钟周期。这里的“最好情况”意味着用于表示锁的数据结构已经在获取和释放锁的 CPU 所属的高速缓存中了。锁操作比 CAS 操作更加耗时,是因深入理解并行编程

为锁操作的数据结构中需要两个原子操作。缓存未命中消耗大概 140 纳秒,超过 200 个时钟周期。需要在存储新值时查询变量的旧值的 CAS 操作,消耗大概 300 纳秒,超过 500 个时钟周期。想想这个,在执行一次 CAS 操作的时间里,CPU 可以执行 500 条普通指令。这表明了细粒度锁的局限性。

以下是cache miss cas 和lock的性能对比:
在这里插入图片描述

4、CAS算法在JDK中的应用

在原子类变量中,如java.util.concurrent.atomic中的AtomicXXX,都使用了这些底层的JVM支持为数字类型的引用类型提供一种高效的CAS操作,而在java.util.concurrent中的大多数类在实现时都直接或间接的使用了这些原子变量类。

Java 1.7中AtomicInteger.incrementAndGet()的实现源码为:
在这里插入图片描述

在这里插入图片描述

由此可见,AtomicInteger.incrementAndGet的实现用了乐观锁技术,调用了类sun.misc.Unsafe库里面的 CAS算法,用CPU指令来实现无锁自增。所以,AtomicInteger.incrementAndGet的自增比用synchronized的锁效率倍增。

Java面试必问的CAS原理剖析 CAS(Compare-And-Swap)是比较并交换的意思,它是一条 CPU 并发原语,用于判断内存中某个值是否为预期值,如果是则更改为新的值,这个过程是原子的。下面用一个小示例解释一下。CAS机制当中使用了3个基本操作数:内存地址V,旧的预期值A,计算后要修改后的新值B。(1)初始状态:在内存地址V中存储着变量值为 1。(2)线程1想要把内存地址为 V 的变量值增加1。这个时候对线程1来说,旧的预期值A=1,要修改的新值B=2。 阅读详情

相关推荐

中移物联ML307C模组OPENCPU笔记2

本文介绍了如何编译和运行一个DEMO程序,以官方SDK为例。

weixin_43700831的博客 1887

java---CAS原理分析详解

CAS的全称为Compare-And-Swap,它是一条CPU同步原语,是一种硬件对并发的支持。它的功能是判断内存某个位置的值是否为预期值,如果是则更新为新的值,这个过程是原子的

m0_58196614的博客 2973

Voxel Hashing技术解析:如何解决TSDF内存爆炸问题?

本文深入解析Voxel Hashing技术如何有效解决TSDF内存爆炸问题。通过动态内存分配和空间哈希函数设计,该技术将内存占用降低96.6%,同时保持高精度重建。文章详细介绍了GPU加速实现、现代系统演进及实践指南,为实时3D重建提供工程解决方案。

m2n3b4v5c6的博客 715

Java实现CAS的原理

CAS(Compare and Swap)是一种并发编程中的技术,用于实现多线程之间的原子操作。它允许你比较一个内存位置的值和一个预期的值,如果相等,则将新值设置到该内存位置,从而实现原子性的修改操作。CAS是乐观锁,线程执行的时候不会加锁,假设没有冲突去完成某项操作,如果因为冲突失败了就重试,最后直到成功为止。虽然CAS存在这三大问题,但在很多情况下仍然是非常有用的,并且在并发编程中发挥着重要的作用。

无简介 915

eNSP-交换机VLAN配置

VLAN

乌托托的博客 8810

深入解析高通Adreno DPU的DRM/KMS驱动架构与硬件协同设计

本文深入解析了高通Adreno DPU的DRM/KMS驱动架构与硬件协同设计,详细介绍了Adreno DPU的核心模块组成、显示接口设计以及DRM驱动架构。通过实际案例和调试技巧,帮助开发者理解硬件与软件的协同工作原理,优化显示性能并解决常见问题。

weixin_29266679的博客 439

java的CAS原理

CAS原理

zmt0104的博客 1318

开关电源和线性电源Multisim电路仿真实验汇总——硬件工程师笔记

本文系统介绍了稳压电源的基础知识与应用实验。首先阐述了稳压电源的定义与类型,包括线性稳压电源(如LM7805/7905)和开关稳压电源(降压/升压/升降压式)的工作原理、参数特点及优劣势。随后详细讲解了各类稳压电源的实验设计,如线性稳压电源的电路实现、开关稳压电源的PWM控制方法等。最后汇总了硬件工程师相关的笔试面试资源,涵盖器件知识、电路仿真、企业真题等内容。全文结合理论分析与Multisim仿真,为电子工程学习者提供了稳压电源的实用技术参考。

XU157303764的博客 1641

Java中CAS原理详解

volatile是Java虚拟机提供的轻量级的同步机制,拥有三大特性 保证可见性 不保证原子性 禁止指令重排 2.JMM你谈谈 JMM(Java内存模型Java Memory Model,简称JMM)本身是一种抽象的概念 并不真实存在,它描述的是一组规则或规范通过规范定制了程序中各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式. JMM关于同步规定: 1.线程解锁前,必须把共...

群鸟飞扬 5787

自注意力机制(SelfAttention Mechanism)原理与代码实战案例讲解

自注意力机制(Self-Attention Mechanism)原理与代码实战案例讲解 作者:禅与计算机程序设计艺术 / Zen and the Art of Computer Programming 1. 背景介绍

AI天才研究院 1294

雷达方程从零开始的详细推导及实现

通过以上六步,我们从最基本的物理图像出发,完整地推导出了雷达方程。初学者可以按照这个逻辑,自己在纸上一步步重现整个过程。Python实现。

VectorShift的博客 338

Java并发编程(三)—CAS的原理及应用场景

CAS通过比较并交换的方式来更新共享变量,避免了使用传统锁机制带来的性能开销,但在高并发场景下可能会遇到自旋消耗CPU资源和ABA问题等。

echola_mendes的博客 2369

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Java CAS底层原理

Java CAS底层原理 Java CAS底层原理,这一篇就够了!!! CAS全称(Conmpare And Swap)比较并交换,是一种用于在多线程环境下实现同步功能的机制。CAS 操作包含三个操作数 – 内存地址、预期值和新值。CAS 的实现逻辑是将内存地址的数值与预期数值想比较,若相等,则将内存位置处的值替换为新值。若不相等,则不做任何操作。 JAVA中CAS是通过自旋操作完成赋值,若值不相...

Lailai Monkey的博客 6080

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Java CAS 原理分析

CAS 全称是 compare and swap,是一种用于在多线程环境下实现同步功能的机制。CAS 操作包含三个操作数 -- 内存位置、预期数值和新值。CAS 的实现逻辑是将内存位置处的数值与预期数值想比较,若相等,则将内存位置处的值替换为新值。若不相等,则不做任何操作。在 Java 中,Java 并没有直接实现 CAS,CAS 相关的实现是通过 C++ 内联汇编的形式实现的。Java 代码需通过 JNI 才能调用。关于实现上的细节,我将会在第3章进行分析。前面说了 CAS 操作的流程,并不是很难。

攻城狮不是猫 889

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Java 的 CAS原理

Java 的 CAS原理 ​ – 借鉴爱编码,来这里分享一下 简介 在计算机科学中,比较和交换(Conmpare And Swap)是用于实现多线程同步的原子指令。它将内存位置的内容与给定值进行比较,只有在相同的情况下,将该内存位置的内容修改为新的给定值。这是作为单个原子操作完成的。 原子性保证新值基于最新信息计算; 如果该值在同一时间被另一个线程更新,则写入将失败。操作结果必须说明是否进行替换; 这可以通过一个简单的布尔响应(这个变体通常称为比较和设置),或通过返回从内存位置读取的值来完成。 核心思想

qq_43644023的博客 379

java CAS原理和用法

CAS(Compare-And-Swap)是一种无锁原子操作机制,通过比较内存值与预期值来决定是否更新,整个过程不可分割。Java通过java.util.concurrent.atomic包提供原子类实现CAS,如AtomicInteger和AtomicStampedReference(解决ABA问题)。其优点是高性能、避免死锁,但存在ABA问题和自旋开销。核心方法compareAndSet()保证了线程安全,适用于低竞争场景。

zfj321的博客 2159

Java中的CAS及其实现原理

一、理解CAS 什么是CAS? CAS:Compare and Swap,即比较再交换。 jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronouse同步锁的一种乐观锁。JDK 5之前Java语言是靠synchronized关键字保证同步的,这是一种独占锁,也是是悲观锁。 CAS算法理解 对CAS的理解,CAS是一种...

沉默的夏虫 1637

Java的CAS原理

Java的CAS原理 一、CAS原理    CAS是compare and swap,意思是比较并交换      java.util.concurrent包中借助CAS实现。   CAS操作包含三个操作数——内存位置V、预期原值A、新值B。如果内存位置和预期原值相同,那么处理器会自动的将该位置的值更新为新值,否则处理器不做生命和操作。无论那种情况,都会在CAS指令之前返回该位置的值。   悲观锁:...

北巷以南猫 439

Java的CAS原理与应用

CAS是一种无锁算法,该算法关键依赖两个值——期望值(旧值)和新值,底层CPU利用原子操作判断内存原值与期望值是否相等,如果相等就给内存地址赋新值,否则不做任何操作。使用CAS进行无锁编程的步骤大致如下:1、获得字段的期望值(oldValue)。2、计算出需要替换的新值(newValue)。3、通过CAS将新值(newValue)放在字段的内存地址上,如果CAS失败就重复第1步到第2步,一直到CAS成功,这种重复俗称CAS自旋。

Artisan_w 1406

Java CAS 原理

在每次进行 CAS 操作时,不仅需要比较要修改的内存地址的值与期望的值是否相等,还需要比较这个内存地址的版本号是否与期望的版本号相等。这样就造成了内存可见性问题,当某个线程修改了主存中的共享变量值之后,其他线程不能感知到该线程被修改了,它会一直使用自己工作内存中的旧值。实现 CAS 大致的原理是:将需要操作的变量读进线程工作空间,比较工作空间的值和主缓存的值,如果工作空间缓存的值和主缓存的值相等,修改工作空间缓存并将修改后的值写入主缓存,如果不相等,则失败。// 11 (返回旧值,再+1)

hanjie13141516的博客 891

【Java并发】CAS原理

CAS是英文单词的缩写,翻译过来就是比较并替换。CAS机制当中使用了3个基本操作数:内存地址V,旧的预期值A,要修改的新值B。更新一个变量的时候,只有当变量的预期值A和内存地址V当中的实际值相同时,才会将内存地址V对应的值修改为B。从思想上来说,Synchronized属于,悲观地认为程序中的并发情况严重,所以严防死守。CAS属于,乐观地认为程序中的并发情况不那么严重,所以让线程不断去尝试更新。Synchronized关键字会让没有得到锁资源的线程进入状态,而后在争夺到锁资源后恢复为。

知归 1035

价值上万的 Java CAS 原理剖析,全是干货。

在Java并发中,我们最初接触的应该就是synchronized关键字了,但是synchronized属于重量级锁,很多时候会引起性能问题,volatile也是个不错的选择,但是volatile不能保证原子性,只能在某些场合下使用。 像synchronized这种独占锁属于悲观锁,它是在假设一定会发生冲突的,那么加锁恰好有用,除此之外,还有乐观锁,乐观锁的含义就是假设没有发生冲突,那么我正好可以进行某项操作,如果要是发生冲突呢,那我就重试直到成功,乐观锁最常见的就是CAS。 这里插一句,我整理了免费的Ja.

程序员Monkey的专栏 4432

java cas原理_什么是 Java 中的 Unsafe 与 CAS ?

Unsafe简单讲一下这个类。Java 无法直接访问底层操作系统,而是通过本地(native)方法来访问。不过尽管如此,JVM 还是开了一个后门,JDK 中有一个类 Unsafe,它提供了硬件级别的原子操作。这个类尽管里面的方法都是 public 的,但是并没有办法使用它们,JDK API 文档也没有提供任何关于这个类的方法的解释。总而言之,对于 Unsafe 类的使用都是受限制的,只有授信的代码...

weixin_39769675的博客 66
上一篇: SQL常用连接查询
下一篇: Redis集群搭建,几种模式介绍
小亮彡
博客等级 码龄7年 6粉丝 22原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值