Java中CAS操作详解

Java中的CAS(Compare and Swap)操作及其用途详解 假设V的值原来是A,后来被其他线程改成了B,然后又改回A,那么当前线程进行CAS操作的时候,发现V的值仍然是A,然后它就会将V的值设置为B。Java中的java.util.concurrent.atomic包提供了大量的原子类,如AtomicInteger、AtomicLong、AtomicReference等,这些类内部都使用了CAS操作来实现线程安全的原子操作。无论哪种情况,都返回位置V的值。:CAS操作本身是原子的,这意味着在多线程环境下,CAS操作能够确保数据的一致性,避免了数据竞争和脏读等问题。 阅读详情

在JDK 5之前Java语言是靠synchronized关键字保证同步的,这会导致有锁

锁机制存在以下问题:

(1)在多线程竞争下,加锁、释放锁会导致比较多的上下文切换和调度延时,引起性能问题。

(2)一个线程持有锁会导致其它所有需要此锁的线程挂起。

(3)如果一个优先级高的线程等待一个优先级低的线程释放锁会导致优先级倒置,引起性能风险。

volatile是不错的机制,但是volatile不能保证原子性。因此对于同步最终还是要回到锁机制上来。

独占锁是一种悲观锁,synchronized就是一种独占锁,会导致其它所有需要锁的线程挂起,等待持有锁的线程释放锁。而另一个更加有效的锁就是乐观锁。所谓乐观锁就是,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。乐观锁用到的机制就是CAS,Compare and Swap。

一、什么是CAS

CAS,compare and swap的缩写,中文翻译成比较并交换。

我们都知道,在java语言之前,并发就已经广泛存在并在服务器领域得到了大量的应用。所以硬件厂商老早就在芯片中加入了大量直至并发操作的原语,从而在硬件层面提升效率。在intel的CPU中,使用cmpxchg指令。

在Java发展初期,java语言是不能够利用硬件提供的这些便利来提升系统的性能的。而随着java不断的发展,Java本地方法(JNI)的出现,使得java程序越过JVM直接调用本地方法提供了一种便捷的方式,因而java在并发的手段上也多了起来。而在Doug Lea提供的cucurenct包中,CAS理论是它实现整个java包的基石。

CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。无论哪种情况,它都会在 CAS 指令之前返回该位置的值。(在 CAS 的一些特殊情况下将仅返回 CAS 是否成功,而不提取当前值。)CAS 有效地说明了“我认为位置 V 应该包含值 A;如果包含该值,则将 B 放到这个位置;否则,不要更改该位置,只告诉我这个位置现在的值即可。”(CAS保存了V位置的原来A值,当再次去访问时,若还是旧A,则替换成B,否则,不替换)

通常将 CAS 用于同步的方式是从地址 V 读取值 A,执行多步计算来获得新值 B,然后使用 CAS 将 V 的值从 A 改为 B。如果 V 处的值尚未同时更改,则 CAS 操作成功。

类似于CAS 的指令允许算法执行读-修改-写操作,而无需害怕其他线程同时修改变量,因为如果其他线程修改变量,那么 CAS 会检测它(并失败),算法可以对该操作重新计算。

二、CAS的目的

利用CPU的CAS指令,同时借助JNI来完成Java的非阻塞算法。其它原子操作都是利用类似的特性完成的。而整个J.U.C都是建立在CAS之上的,因此对于synchronized阻塞算法,J.U.C在性能上有了很大的提升。

三、CAS存在的问题

CAS虽然很高效的解决原子操作,但是CAS仍然存在三大问题。ABA问题,循环时间长开销大和只能保证一个共享变量的原子操作

  1. ABA问题。因为CAS需要在操作值的时候检查下值有没有发生变化,如果没有发生变化则更新,但是如果一个值原来是A,变成了B,又变成了A,那么使用CAS进行检查时会发现它的值没有发生变化,但是实际上却变化了。ABA问题的解决思路就是使用版本号。在变量前面追加上版本号**,每次变量更新的时候把版本号加**一,那么A-B-A 就会变成1A-2B-3A。

从Java1.5开始JDK的atomic包里提供了一个类AtomicStampedReference来解决ABA问题。这个类的compareAndSet方法作用是首先检查当前引用是否等于预期引用,并且当前标志是否等于预期标志,如果全部相等,则以原子方式将该引用和该标志的值设置为给定的更新值。

关于ABA问题参考文档:原文链接

  1. 循环时间长开销大。自旋CAS如果长时间不成功,会给CPU带来非常大的执行开销。如果JVM能支持处理器提供的pause指令那么效率会有一定的提升,pause指令有两个作用,第一它可以延迟流水线执行指令(de-pipeline),使CPU不会消耗过多的执行资源,延迟的时间取决于具体实现的版本,在一些处理器上延迟时间是零。第二它可以避免在退出循环的时候因内存顺序冲突(memory orderviolation)而引起CPU流水线被清空(CPU pipelineflush),从而提高CPU的执行效率。

  2. 只能保证一个共享变量的原子操作。当对一个共享变量执行操作时,我们可以使用循环CAS的方式来保证原子操作,但是对多个共享变量操作时,循环CAS就无法保证操作的原子性,这个时候就可以用锁,或者有一个取巧的办法,就是把多个共享变量合并成一个共享变量来操作。比如有两个共享变量i=2,j=a,合并一下ij=2a,然后用CAS来操作ij。从Java1.5开始JDK提供了AtomicReference类来保证引用对象之间的原子性,你可以把多个变量放在一个对象里来进行CAS操作。

四、concurrent包的实现

由于java的CAS同时具有 volatile 读和volatile写的内存语义,因此Java线程之间的通信现在有了下面四种方式:

  1.  A线程写volatile变量,随后B线程读这个volatile变量。
    
  2.  A线程写volatile变量,随后B线程用CAS更新这个volatile变量。
    
  3.  A线程用CAS更新一个volatile变量,随后B线程用CAS更新这个volatile变量。
    
  4.  A线程用CAS更新一个volatile变量,随后B线程读这个volatile变量。
    

Java的CAS会使用现代处理器上提供的高效机器级别原子指令,这些原子指令以原子方式对内存执行读-改-写操作,这是在多处理器中实现同步的关键(从本质上来说,能够支持原子性读-改-写指令的计算机器,是顺序计算图灵机的异步等价机器,因此任何现代的多处理器都会去支持某种能对内存执行原子性读-改-写操作的原子指令)。同时,volatile变量的读/写和CAS可以实现线程之间的通信。把这些特性整合在一起,就形成了整个concurrent包得以实现的基石。如果我们仔细分析concurrent包的源代码实现,会发现一个通用化的实现模式:

1. 首先,声明共享变量为volatile;

2. 然后,使用CAS的原子条件更新来实现线程之间的同步;

3. 同时,配合以volatile的读/写和CAS所具有的volatile读和写的内存语义来实现线程之间的通信。

AQS加粗样式,非阻塞数据结构和原子变量类(java.util.concurrent.atomic包中的类),这些concurrent包中的基础类都是使用这种模式来实现的,而concurrent包中的高层类又是依赖于这些基础类来实现的。从整体来看,concurrent包的实现示意图如下:
在这里插入图片描述
版权声明:本文为优快云博主「郑学炜」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:传送门

Java中的CAS(Compare-And-Swap)操作详解 在Java中,CAS操作通常通过。方法使用CAS操作实现了对。方法,确保在多线程环境下对。类就提供了基于CAS的。包中的类来实现,例如。 阅读详情

相关推荐

Unsafe 类详解:Java 中的“后门”,原子操作 CAS 到底是如何实现的?

Unsafe 是 Java 中绕过 JVM 安全检查直接操作内存的"后门",为并发编程提供了底层支持。其核心 CAS(比较并交换)操作通过三步实现原子性更新:1)获取内存地址值;2)比较预期值;3)条件成立则更新。从 Java 代码到 CPU 指令,CAS 经历了多层转换:Java 调用委托给 Unsafe,再通过 JVM 本地方法转为 C++ 实现,最终映射为 x86 的 lock cmpxchg 汇编指令,由 CPU 的缓存锁定机制保证原子性。此外,Unsafe 还支持线程调度、堆外

BUG猿的博客 885

java多线程操作之CAS

CAS(Compare-And-Swap) 比较并交换,用于实现同步和锁机制。经常配合juc中Atomic相关类进行。

weixin_54925172的博客 1312

华为交换机密码策略配置避坑指南:明文/密文、长度、复杂度,一个命令就出错

本文详细解析华为交换机密码策略配置的关键要点,包括密码长度、复杂度及等保合规要求。通过实战案例揭示常见配置误区,如明文/密文密码格式差异、复杂度检查联动机制等,帮助网络工程师避免安全漏洞。特别针对等保二级和三级要求,提供可直接落地的安全加固方案。

weixin_30879169的博客 368

Java中的CAS操作

Java中的CAS操作

weixin_55079859的博客 1130

dToF直方图之美

上面视频里如果你能看懂,那么就能理解对于dToF单点的测距问题,对于大部分的描述在AMS和ST里的手册都非常的详细,有疑问的可以后台来找我探讨,今天我们单纯从上层讨论成像的问题。作为dToF算法工程师,应该是对直方图敏感的,直方图的每个Count峰都会表征出问题,因为dToF的输出只有直方图,观察直方图能够逆推出dToF的很多东西,这也是大多数公司不愿意开放直方图和Raw data的缘故。以上是一个小面阵的分辨率,第一张是直方图,后面是基于直方图寻峰出来的成像ToF图,Peak图,以及噪声Noise图。

dream it possible 2992

【QNX+Android虚拟化方案】01 - 芯片介绍

【QNX+Android虚拟化方案】01 - 芯片介绍

|~~~热爱生活、努力学习的小伙汁~~~| 2945

Java中CAS详解

目录 什么是CAS 从一个案例引出CAS问题 Java中的Atomic 原子操作包 1. 基本原子类 2. 数组原子类 3. 引用原子类 4. 字段更新原子类 类 AtomicInteger 常用的方法: AtomicInteger 案例: AtomicInteger 源码解析: Unsafe类 Unsafe 提供的 CAS 方法 调用 Unsafe 提供的偏移量相关 什么是CAS CAS,compare and swap的缩写,中文翻译成比较并交换。 CAS 操作包含三个

lwang_IT的博客 3万+

基于YOLOv10的建筑图纸物体检测系统:从数据集构建到UI界面实现

高度结构化的图形元素标准化的符号和标注系统多层次的细节表达精确的尺寸和位置关系。

YOLO 389

【JavaEE】CAS操作

对此,小明开始了第二次取钱操作,在他刚刚操作好第二次前,第一次取钱操作被启动了,卡里的余额只剩50,那么这第二次取钱操作就会失败。这是一个正常的情况,问题是,如果在第一次取钱操作执行后,小明的朋友又给小明卡里打了50块钱,卡里的余额又变成了100,那么第二次取钱操作就会成功执行,这下就会执行两次取款操作,跟小明的预期不符,就会产生BUG。要知道,在多线程中,这种比较和赋值中是很容易出现线程安全问题的,CAS的原子性,就是它最大的价值。,上面的比较和赋值是一步同时完成的,它只是CPU上的一条指令。

qq_63230990的博客 537

PCIe协议之 Equalization篇 之 理论篇 之 FFE

作为最后一道“精加工”工序,DFE利用其不放大噪声的优势,精准地消除残余的、强烈的后光标ISI,最终得到一个非常干净、张得很开的眼图,供判决器使用。信号经过信道衰减后变得模糊,首先由CTLE进行“粗调”,提供一个宽频带的增益,将眼图初步打开,为后面的DFE创造一个可以正常工作的信号环境。,它通过将输入信号在不同时间点上的多个副本(称为“抽头”)进行加权求和,来直接塑造或“整形”输出信号的波形。:这是最主要的信号路径,通常系数为正值,决定了信号的幅度。:将所有加权后的信号相加,产生最终的均衡输出。

那么菜的博客 752

【企业智能体开发】优化模型成本、延迟与失败降级

小林的培训快开始时,服务台花很久“思考最优回答”,体验并不会更好。反过来,为了省钱而始终选最轻的模型,若连房间、连接方式和任务状态都识别不稳,后续错误检索和重复建单会造成更大代价。企业 Agent 的优化对象不是单次模型调用价格,而是任务在可接受时间内、安全地推进到正确结果的总成本。

Mr数据杨 893

【Java基础】CAS (Compare And Swap) 操作

CAS其实就是Compare And Swap的一个缩写,顾名思义就是比较并交换,其实就是把当前值与你预期的值进行一个比较,是一种用于在多线程环境下实现同步功能的机制。

fumeidonga的博客 3250

大数据在电力行业的应用案例解析-【电力技术】(九)大数据在电力储能运维中的深度应用(含故障预测代码)

大数据技术为电力储能运维提供了“精准化、智能化、高效化”的解决方案,破解了传统运维的核心痛点,实现了储能系统从“被动抢修”到“主动运维”的转型,为新型电力系统建设提供了重要支撑。当前,随着储能产业的快速发展,大数据与储能运维的融合将更加深入,未来将结合人工智能、物联网、区块链等技术,实现储能运维的全流程智能化——从设备故障的提前预警,到寿命的精准预测,再到运维策略的自动优化、调度协同的实时响应,进一步提升储能系统的安全性、经济性与可靠性。

getusushu的博客 87

14.Java中CAS操作详解

在JDK 5之前Java语言是靠synchronized关键字保证同步的,这会导致有锁锁机制存在以下问题:(1)在多线程竞争下,加锁、释放锁会导致比较多的上下文切换和调度延时,引起性能问题。(2)一个线程持有锁会导致其它所有需要此锁的线程挂起。(3)如果一个优先级高的线程等待一个优先级低的线程释放锁会导致优先级倒置,引起性能风险。volatile是不错的机制,但是volatile不能保证原子性。因...

郑学炜的技术博客 953

从数据库到数据仓库:数据仓库导论

本文为数据仓库导论,旨在介绍数据仓库的基本理念和应用场景,帮助读者理解数据仓库的重要性及其在企业中的实际应用。

探索大数据世界 - 深入解析数据存储、分布式计算与人工智能 2784

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

java中的CAS操作以及锁机制详解

关于CAS操作 CAS:Compare And Swap   --  乐观锁策略 CAS(无锁操作):使用CAS叫做比较交换来判断是否出现冲突,出现冲突就重试当前操作直到不冲突为止。 悲观锁(JDK1.6之前的内建锁):假设每一次执行同步代码块均会产生冲突,所以当线程获取锁成功,会阻塞其他尝试获取该锁的线程。 乐观锁(Lock机制):假设所有线程访问共享资源时不会出现冲突,既然不会出现冲突...

【Dyson】的博客 9717

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

JAVA cas 参数_Java CAS操作与Unsafe类详解

一、复习计算机内存模型,synchronized和volatile关键字简介二、两者对比sychronized和volatile都解决了内存可见性问题不同点:(1)前者是独占锁,并且存在者上下文切换的开销以及线程重新调度的开销;后者是非阻塞算法,不会造成上下文切换的开销。(2)前者可以保证操作的原子性,但是后者不能保证操作的原子性。三、在什么情况下才会使用volatile写入变量是不依赖当前值的,...

weixin_39795268的博客 337

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

java cas 同步_无锁的同步策略——CAS操作详解

2. CAS详解Java中的CAS操作依赖于底层CPU的CAS指令。2.1 CAS指令CAS,即Compare-and-Swap(比较和交换),从语义上它需要两次操作,但只需要一条cpu指令就能完成,因而该操作具有原子性,像原子一样不可分割,要么成功,要么失败。CAS指令需要3个操作数,分别是V:变量的内存地址,A(预期值),B(更新值)。CAS指令执行时,只有当预期值A和V的值一样时才进行更新,...

weixin_39528219的博客 335

java中乐观锁CAS操作详解

什么是乐观锁 乐观锁就是假设所有线程访问共享资源都不会出现冲突,由于不会出现冲突所以就不会也不需要去阻塞其他线程。因此线程不会出现阻塞等待的状态。但是一旦发生冲突时,无锁操作,会使用CAS操作来鉴别线程是否出现冲突,出现冲突了就重复尝试,直到没有冲突为止。 什么时CAS操作。 CAS操作就是Compare And Swap比较交换操作。 在CAS中操作中,有三个值。V,O,N。 V:当前内存中存放...

坚持不懈做贡献 1479

Java面试必备:Java中的CAS(Compare-And-Swap)操作详解

CAS(Compare-And-Swap,比较并交换)是一种原子操作,用于在多线程环境中实现无锁(lock-free)的线程安全编程。它是现代并发编程中的基础操作之一,Java中的许多并发工具类(如AtomicInteger、AtomicReference等)都是基于CAS实现的。

qq_58299462的博客 1897

java unsafe 详解_Java CAS操作与Unsafe类详解

一、复习计算机内存模型,synchronized和volatile关键字简介二、两者对比sychronized和volatile都解决了内存可见性问题不同点:(1)前者是独占锁,并且存在者上下文切换的开销以及线程重新调度的开销;后者是非阻塞算法,不会造成上下文切换的开销。(2)前者可以保证操作的原子性,但是后者不能保证操作的原子性。三、在什么情况下才会使用volatile写入变量是不依赖当前值的,...

weixin_35411561的博客 160

什么是原子性操作java_Java CAS操作与Unsafe类详解

一、复习计算机内存模型,synchronized和volatile关键字简介二、两者对比sychronized和volatile都解决了内存可见性问题不同点:(1)前者是独占锁,并且存在者上下文切换的开销以及线程重新调度的开销;后者是非阻塞算法,不会造成上下文切换的开销。(2)前者可以保证操作的原子性,但是后者不能保证操作的原子性。三、在什么情况下才会使用volatile写入变量是不依赖当前值的,...

weixin_33212486的博客 318

Java高并发9-CAS操作与Unsafe类详解

一、复习 计算机内存模型,synchronized和volatile关键字简介 二、两者对比 sychronized和volatile都解决了内存可见性问题 不同点: (1)前者是独占锁,并且存在者上下文切换的开销以及线程重新调度的开销;后者是非阻塞算法,不会造成上下文切换的开销。 (2)前者可以保证操作的原子性,但是后者不能保证操作的原子性。 三、在什么情况下才会使用volatile 写入变量是不依赖当前值的,如果是依赖当前值的话,由于获取-计算-写入,三者不是原子性操作,而volatile是保

weixin_44630050的博客 226

Java并发编程原理精讲:CAS与Atomic原子操作详解

线程1读取内存值A,准备CAS修改;期间线程2将值A改为B,再改回A;线程1比对内存值依旧为A,判定变量未修改,直接执行修改,忽略变量中间篡改流程,即为ABA问题。

只要肯攀登,终有登顶时 350

Java精通并发-CAS详解及透过字节码分析变量操作的原子性

CAS: 背景: 继续Java并发的学习,这次开启新知识的学习,如标题所示---CAS,要想理解它,得先从一些背景知识了解起。 1、synchronized关键字与Lock等锁机制都是悲观锁:从字面意思来理解就是说线程在操作数据的时候是很悲观的,所谓这个“悲观”是指它认为一定会有其它的线程与我争抢,所以为了保证我操作数据的安全,“一定”是先上锁再来操作数据,避免其它线程干扰我。所以它的特点是无论做任何操作,首先都需要先上锁,接下来再去执行后续操作,从而确保了接下来的操作都是由当前这个线程来执行。 2

webor2006的博客 241
上一篇: 百度地图API的接入
下一篇: 美年旅游项目总结
lijian_365
博客等级 码龄7年 9粉丝 14原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值