java CAS详解[通俗易懂]

java CAS详解[通俗易懂]CAS解释:CAS(compareandswap),比较并交换。可以解决多线程并行情况下使用锁造成性能损耗的一种机制.CAS操作包含三个操作数—内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。一个线程从主内存中得到num值,并对num进行操作,写入值的时候,线程会把第一次取到的num值和主内存中num值进行比较,如果相等,就会将改变后的num写入主内存,如果不相等,则一直循环对比,知道成功为止。CAS

大家好,又见面了,我是你们的朋友全栈君。

CAS解释:

CAS(compare and swap),比较并交换。可以解决多线程并行情况下使用锁造成性能损耗的一种机制.CAS 操作包含三个操作数—内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。一个线程从主内存中得到num值,并对num进行操作,写入值的时候,线程会把第一次取到的num值和主内存中num值进行比较,如果相等,就会将改变后的num写入主内存,如果不相等,则一直循环对比,知道成功为止。

CAS产生:

在修饰共享变量的时候经常使用volatile关键字,但是volatile值有可见性和禁止指令重拍(有序性),无法保证原子性。虽然在单线程中没有问题,但是多线程就会出现各种问题,造成现场不安全的现象。所以jdk1.5后产生了CAS利用CPU原语(不可分割,连续不中断)保证现场操作原子性。

CAS应用:

在JDK1.5 中新增java.util.concurrent(JUC)就是建立在CAS之上的。相对于对于synchronized这种锁机制,CAS是非阻塞算法的一种常见实现。所以JUC在性能上有了很大的提升。

比如AtomicInteger类,AtomicInteger是线程安全的的,下面是源码

java CAS详解[通俗易懂]

java CAS详解[通俗易懂]

进入unsafe看到do while自循环,这里的自循环,就是在 判断预期原值 如果与原来的值不符合,会再循环取原值,再走CAS流程,直到能够把新值赋值成功。

CAS优点

cas是一种乐观锁的思想,而且是一种非阻塞的轻量级的乐观锁,非阻塞式是指一个线程的失败或者挂起不应该影响其他线程的失败或挂起的算法。

CAS 缺点

  1. 循环时间长开销大,占用CPU资源。如果自旋锁长时间不成功,会给CPU带来很大的开销。如果JVM能支持处理器提供的pause指令那么效率会有一定的提升,pause指令有两个作用,第一它可以延迟流水线执行指令(de-pipeline),使CPU不会消耗过多的执行资源,延迟的时间取决于具体实现的版本,在一些处理器上延迟时间是零。第二它可以避免在退出循环的时候因内存顺序冲突(memory order violation)而引起CPU流水线被清空(CPU pipeline flush),从而提高CPU的执行效率。
  2. 只能保证一个共享变量的原子操作。当对一个共享变量执行操作时,我们可以使用循环CAS的方式来保证原子操作,但是对多个共享变量操作时,循环CAS就无法保证操作的原子性,这个时候就可以用锁,或者有一个取巧的办法,就是把多个共享变量合并成一个共享变量来操作。比如有两个共享变量i=2,j=a,合并一下ij=2a,然后用CAS来操作ij。从Java1.5开始JDK提供了AtomicReference类来保证引用对象之间的原子性,你可以把多个变量放在一个对象里来进行CAS操作。
  3. ABA问题

      解决ABA问题(如果值考虑收尾,不考虑过程可以忽略改问题)

  1. 添加版本号
  2. AtomicStampedReference
    java CAS详解[通俗易懂]

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

CAS使用的时机

  1. 线程数较少、等待时间短可以采用自旋锁进行CAS尝试拿锁,较于synchronized高效。
  2. 线程数较大、等待时间长,不建议使用自旋锁,占用CPU较高
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/156238.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 零基础学Java(3)运算符

    零基础学Java(3)运算符运算符运算符用于连接值。Java提供了一组丰富的算术和逻辑运算符以及数学函数。算术运算符在Java中,使用算术运算符+、-、*、/表示加、减、乘、除运算。当参与/运算的两个操作数都是整数时,表示

  • Socket java.net.SocketException: Connection reset的解决方案[通俗易懂]

    Socket java.net.SocketException: Connection reset的解决方案[通俗易懂]背景:服务端通讯方式:TCP/IPsocket短链接。首先看下我的最开始的socket代码:publicstaticbyte[]sendMessage(Stringurl,intport,byte[]request,inttimeout){byte[]res=null;Socketsocket=n

  • js/es6判断对象是否为空,并判断对象是否包含某个属性

    js/es6判断对象是否为空,并判断对象是否包含某个属性js判断对象为空以及有好几种方法了,但是个人觉得不是特别方便。比如:1、把对象通过JSON.stringify转为字符串,再判断字符串是否等于”{}”2、forin循环,判断key是否存在3、jq的方法es6已经帮我们很好的解决了此类问题。es6针对对象增加了3个新方法(数组也有):(1)、Object.keys:返回一个数组,成员是参数对象自身的(不含继承…

  • ILRuntime学习[通俗易懂]

    ILRuntime学习[通俗易懂]ILRuntime介绍ILRuntime项目为基于C#的平台(例如Unity)提供了一个纯C#实现,快速、方便且可靠的IL运行时,使得能够在不支持JIT的硬件环境(如iOS)能够实现代码的热更新ILRuntime优势访问C#工程的现成代码,无需额外抽象脚本API直接使用VS2015进行开发,ILRuntime的解译引擎支持.Net4.6编译的DLL执行效率是L#的10-20倍选…

    2022年10月25日
  • 正则匹配数组全部是数字[通俗易懂]

    正则匹配数组全部是数字[通俗易懂]var value=[“2″,”3”]   varv=value.join(“”);varreg=/^\d+$/g;if(!v.match(reg)){//是否匹配到了数字,未匹配到就不是return;}if(v.match(reg)[0].lengthreturn;}

  • python怎么安装requests库-小白安装python的第三方库:requests库

    1.安装:按照教程中的步骤是:Step1:以管理员身份打开command控制台Step2:键入pipinstallrequests对其进行安装然而实际经历是:出现’pip’不是内部或外部命令,也不是可运行的程序或批处理文件。的字样报错经过参考网络上的各种解决方法后,鉴于自己的实际情况→电脑里的python3.6不是安装的,是VS顺带下载的,因此难免缺胳膊少腿,就采取了如下解决步骤。刚安…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号