Java并发基石之CAS原理

一、什么是CAS

  假设现在有多个线程想要操作同一个资源对象,很多人的第一反应就是使用互斥锁,但是互斥锁的同步方式是悲观的。

  什么是悲观呢?简单来说就是操作系统将会悲观地认为如果不严格同步线程的调用,那么一定会产生异常,所以互斥锁将会将资源锁定只供一个线程调用而阻塞其他线程。因此这种同步机制也叫做悲观锁(Pessimistic Concurrency Control),如下图:

  

  但悲观锁不是万能的,比如在一些情况下,大部分调用可能都是读操作,那么就没有必要在每次调用的时候都去锁定资源,或者在一些情况下,同步代码块执行的耗时远远小于线程切换的耗时,那么这就有点本末倒置了。

  

    所以在这些情况下,我们不想让操作系统那么悲观,我们不想过度使用互斥锁,我们的设想中能不能不对共享资源进行锁定,也能对线程调用进行协调。所以后来诞生了一种非常经典和巧妙的算法,叫做CAS (compare and swap)也可以简单理解为比较然后交换。

 

一、CAS工作机制

    假设现在有一个资源变量temp,它有两种状态值1和0,那么此时a线程和b线程看见temp=0时候,于是争抢着去设置temp=1,但是a线程抢先获得了时间片,它将temp的状态改为1,此时B线程才冲过来,但是发现temp上的状态已经被改变,虽然很不服气,但是也得遵守规则,这样你就能够很容易理解CAS。当资源对象的状态值为1的一瞬间,a和b线程都读到了。此时这两条线程认为资源对象当前的状态,只是零,于是他们将会各自产生两个值。Value代表之前读到的资源对象的状态是new value代表想要将资源对象的状态值更新后的值。这里对AB线程来说,Old value都是0,New value都是1,此时一批线程争抢着去修改资源对象的状态值,然后再用它。假设a线程运气比较好,率先获得了时间片,他将evaluate资源对象的状态值进行compare,发现一致,于是将牌子上的值swap为牛柳儿B,线程则没有那么幸运,他落后了一步,此时资源对象的状态是已经被选成修改,成了一。所以必选承载compare的时候,发现和自己预期的value不一致,所以放弃swap操作。但在实际应用中,我们不会让比县城就这样放弃,通常会使其进行自旋。自旋就是17,不断地从事CAS操作,通常会配置资源。选次数来防止死循环,就像B。

   

 

 

 

参考来源:

  https://www.bilibili.com/video/BV1ff4y1q7we?from=search&seid=34455904209770456&spm_id_from=333.337.0.0

posted @ 2021-02-15 17:56  songguojun  阅读(119)  评论(0编辑  收藏  举报