美文网首页
多线程(6) — CAS自旋及问题

多线程(6) — CAS自旋及问题

作者: 烧杰 | 来源:发表于2020-11-18 14:47 被阅读0次

自旋锁CAS:

CAS:Compare and Swap, 即比较交换。
在轻量级锁升级为重量级锁时就用到了自旋锁CAS,同时CAS也可以看作是一种比较交换的思想,在数据库里面的乐观锁也有CAS的思想。通过无锁的操作实现对数据的更新(单个变量),某种程度上保证了数据的一致性和线程的安全性。

CAS算法在Unsafe.class里面的native方法:

public final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5);

CAS算法:CAS是一种无锁算法,CAS有3个参数,内存值V,预期值E,要修改的值N。如果内存中要检测的值V和预期值E相同,则把内存值V修改成目标N,否则则什么都不做。

CAS是通过无限循环来获取数据的,若果在第一轮循环中,a线程获取地址里面的值被b线程修改了,那么a线程需要自旋,到下次循环才有可能机会执行。

CAS存在的三大问题:

1.经典ABA问题
CAS是在需要操作值的时候,检查值有没有变化,如果没有发生变化则更新,但是如果一个值原来是A,变成了B,又变成了A,那么CAS进行检查的时候发现它的值没有发生变化,但是实际上却变化了。ABA问题的解决思路是,每次变量更新的时候把变量的版本号加1,那么A-B-A就会变成A1-B2-A3,只要变量被某一线程修改过,改变量对应的版本号就会发生递增变化,从而解决了ABA问题。从Java 1.5开始,JDK的Atomic包里提供了一个类AtomicStampedReference来解决ABA问题。这个类的compareAndSet方法的作用是首先检查当前引用是否等于预期引用,并且检查当前的标志是否等于预期标志,如果全部相等,则以原子方式将该应用和该标志的值设置为给定的更新值,这样CAS操作中的比较就不依赖于变量值了。

2.自旋循环时间消耗
自旋CAS如果长时间不成功,会给CPU带来非常大的执行开销。解决办法:1.代码层面,破坏掉for死循环,当超过一定时间或者一定次数时,return退出。2. 使用类似ConcurrentHashMap的方法。当多个线程竞争时,将粒度变小,将一个变量拆分为多个变量,达到多个线程访问多个资源的效果,最后再调用sum把它合起来,能降低CPU消耗,但是治标不治本。3.使用JVM能支持处理器提供的pause指令来提升效率。pause指令有两个作用:第一,它可以延迟流水线执行指令(de-pipeline),使CPU不会消耗过多的执行资源,延迟的时间取决于具体实现的版本,在一些处理器上延迟时间是零;第二,它可以避免在循环的时候因内存顺序冲突(Memory Order Violation)而引起CPU流水线被清空,从而提高CPU的实行效率。

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

相关文章

  • 多线程(6) — CAS自旋及问题

    自旋锁CAS: CAS:Compare and Swap, 即比较交换。在轻量级锁升级为重量级锁时就用到了自旋锁C...

  • 2018-06-05

    java基础 cas自旋-基于内存值的判断 基于CAS操作的变量必须声明为Volatile类型,这样多线程操作,能...

  • Java多线程-深入

    CAS Compare And Swap (Compare And Exchange) / 自旋 / 自旋锁 / ...

  • 极简CAS

    CAS 乐观锁 compare and then swap else 自旋 Atomic的核心操作就是CAS(co...

  • Java CAS

    CAS和LockSupport可以说贯穿了java并发包(自旋锁 + CAS + LockSupport + 内存...

  • JAVA 多线程与高并发学习笔记(十四)——AQS核心原理

    基于 CAS自旋实现的轻量级锁在恶性自旋时会消费大量的CPU资源。解决这个问题有2种方案:分散操作热点和使用队列削...

  • 分布式

    1.分布式锁 应用场景:多线程操作共享资源;系统是一个分布式系统,集群 mysql redis:类cas自旋式分布...

  • 深入理解自旋锁

    本文出自:http://blog.onlycatch.com/post/自旋锁 简单回顾一下CAS算法 CAS算法...

  • 【Java 并发编程实战】使用 AQS 实现一个简单的互斥锁

    使用 AQS 实现一个简单的互斥锁 AQS 是什么? 参考[2]。 CAS自旋 CAS 是Compare And ...

  • CAS(自旋锁)

    synchronized能够保证线程安全,但synchronized是重量级锁,性能低;可以使用CAS进行锁优化,...

网友评论

      本文标题:多线程(6) — CAS自旋及问题

      本文链接:https://www.haomeiwen.com/subject/tajsbktx.html