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)


相关推荐

  • mysql报错注入_mysql报错注入[通俗易懂]

    mysql报错注入_mysql报错注入[通俗易懂]报错注入这里主要介绍3种MySQL数据库报错注入的发法,分别是updatexml、floor和exp。1.updatexmlupdatexml的报错原理从本质上来说就是函数的报错。selectupdatexml(1,concat(0x7e,(selectversion()),0x7e),1);这里还是使用前面的例子,举出一个爆破数据库版本的样例Payload:爆破数据库版本信息?id=1’+…

  • 更改nginx默认端口_centos启动nginx

    更改nginx默认端口_centos启动nginx在基于CentOS或RHEL的Linux发行版中,需要安装policycoreutils软件包并添加SELinux对Nginx所需的以下规则以绑定到新端口。这里需要先安装semanage再安装policycoreutils软件包。安装semanage命令:yuminstallsemanage如果提示Nopackagesemanageavailable执行如下命令:yumprovidessemanage以上命令执行成功后,再执行:yum-yinstallpoli

  • jdk源码分析之ArrayList

    ArrayList关键属性分析ArrayList采用Object数组来存储数据/*** The array buffer into which&

    2021年12月26日
  • StringBuffer 详解 (String系列之3)[通俗易懂]

    StringBuffer 详解 (String系列之3)[通俗易懂]本章介绍StringBuffer以及它的API的详细使用方法。转载请注明出处:http://www.cnblogs.com/skywang12345/p/string03.htmlStringBuff

  • hibernate Java 时间和日期类型的 Hibernate 映射

    hibernate Java 时间和日期类型的 Hibernate 映射

    2021年11月29日
  • 怎么查看线程的状态及interrupt优雅的关闭线程和interrupt()、interrupted()、isInterrupted()的作用以及区别在哪?

    怎么查看线程的状态及interrupt优雅的关闭线程和interrupt()、interrupted()、isInterrupted()的作用以及区别在哪?示例:查看状态:刚才我们讲过,一个线程里面任务正常执行完毕,状态就是TERMINATED,就是终止状态。但是,如果我线程里面的任务一直没有执行完成,我想去终止这个线程,或者我给点信息给到线程里,告诉线程我想终止结束呢!所以我可以强制去关闭线程:线程提供一个stop方法,该方法不建议使用,已经过时了!!因为stop是强行关闭线程,线程里面的任务都不在执行,不管线程的任务是否执行成功与否,就算执行到一半也会强制关闭!导致很多不可控制的结果,比如支付付一半等等!!所以我们要需要去优雅的关闭。什么叫做优雅关

    2022年10月25日

发表回复

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

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