查看完整视频
小黑屋思过中,禁止观看!
评论并刷新后可见

您需要在视频最下面评论并刷新后,方可查看完整视频

积分观看

您支付积分,方可查看完整视频

{{user.role.value}}
付费视频

您支付费用,方可查看完整视频

¥{{user.role.value}}
课程视频

开通VIP,畅学所有专题课程视频

会员专享

视频选集

CAS的实现原理剖析,大厂面试必问!

  • 课程笔记
  • 交流讨论

在并发编程中,多线程竞争同一个资源时,一般我们常用的是synchronized等排它锁来解决多线程的资源竞争。

synchronized属于有锁的解决方案,但是加锁、释放锁会导致比较多的上下文切换和调度延时,引起性能问题。

是否可以采用无锁的方式来解决多线程竞争?

CAS就是一个无锁解决方案,更准确的是采用乐观锁技术,但并不是说CAS的方式就是性能最好的,无锁也有它的劣势,文末会谈到它的劣势与应用场景。

为了助大家掌握好CAS,本节课我会重点讲解以下6点:

1.CAS
2.CAS的实现原理
3.CAS的优缺点
4.CAS自旋
5.CAS的ABA问题
6.CAS的总结

什么是CAS

CAS(Compare and swap),即比较并交换,也是实现我们平时所说的自旋锁或乐观锁的核心操作。

Java并发包中的很多类都使用了CAS技术,是实现我们平时所说的自旋锁或乐观锁的核心操作。

CAS的算法

它的实现很简单,就是用一个预期的值和内存值进行比较,如果两个值相等,就用预期的值替换内存值,并返回 true。否则,返回 false。

CAS机制当中使用了3个基本操作数:内存地址V,旧的预期值A,要修改的新值B

更新一个变量的时候,只有当变量的预期值A和内存地址V当中的实际值相同时,才会将内存地址V对应的值修改为B

CAS的实现原理

CAS的实现原理剖析,大厂面试必问!-mikechen的互联网架构师之路

隐藏内容,您需要满足以下条件方可查看
End
5 条回复 A文章作者 M管理员
  1. 李鸿翼

    1.CAS乐观锁,总是假设最好的情况,每次去读数据都认为别人不会修改,所以不会上锁,但更新的时候需要判断该数据是否被人修改过,如果被修改过,则不进行数据更新,如果没有被修改过,进行更新。

    2.synchronized悲观锁,每次获取数据都担心被修改,所以每次获取数据都会进行加锁,使用完后会解锁。在加锁期间,其他对该数据进行读写的线程都会进行等待。

    乐观锁适用于读多写少,并发冲突少的场景;悲观锁适合强一致性的场景,但效率比较低,特别是读的并发低。

    对于资源竞争较少,可以使用乐观锁,因为CAS基于硬件实现,不会进入内核,不需要切换线程,操作自选几率较少,可以获得较高性能;而使用synchronized的悲观锁会进行线程阻塞和唤醒切换,用户态和内核态切换操作额外消费CPU资源。

    对于资源竞争较多,CAS自旋的概率会比较大,从而浪费更多的CPU资源,效率低于synchronized;

    但是在jdk1.6后,synchronized进行了优化,基于Lock-free的队列,基本思路是自旋后阻塞。在线程冲突较少的情况下,可以获得和CAS类似的性能;当线程冲突严重的请款改下,性能高于cas

    • mikechen

      ✗棒棒的✗

  2. 路正银

    CAS乐观锁,总是假设最好的情况,每次去读数据的时候都人为别人不会修改,所以不会上锁,但是在更新的时候
    会判断一下在此期间有没有其他线程更新该数据。
    悲观锁,总是假设最坏的情况,每次去读数据的时候都人为别人会修改,所以每次在读数据的时候都会上锁,这样别人想读取数据就会阻塞直到它获得锁。

    乐观锁的缺点:
    1、ABA问题
    2、自旋时间长开销大
    3、只能保证一个共享变量的原子操作

    悲观锁的缺点:
    1、需要独占资源,
    2、会发生线程阻塞
    3、线程之间切换会发费时间

    乐观锁和悲观锁在部分场景下可以看做相对的两面,优缺点恰好是对照的,一个的缺点恰好是另一个的优点

    乐观锁的悲观锁的优缺点决定了他们的适用场景
    乐观锁适用于写比较少的情况下,在这种场景下用乐观锁可以省去锁的开销,加大系统的吞吐量
    悲观锁适用于多写场景,在多写的情况下,一般会经常产生冲突,这时候用乐观锁会不断的进行自旋,反倒是降低了性能
    资源竞争较少的场景,用乐观锁相比较于悲观锁,可以减少线程之间切换的时间
    资源竞争严重的情况,CAS自旋的概率会比较大,从而浪费更多的CPU资源,效率低于悲观锁

    • mikechen

      优秀 ✗棒棒的✗

  3. JansenZhang

    基于CAS实现的乐观锁在低并发的情况下会比synchronized的效率高,因为不存在加锁解锁的操作。
    但是在多并发的情况下,多个线程都在进行自旋,会导致cpu负载过高。
    synchronized主要是在切换线程时会发生用户态和内核态的切换,也会导致消耗比较多的资源。
    在使用的时候,如果并发量不大,推荐CAS锁。