当前位置: 首页 > news >正文

CAS详谈---无锁的锁机制

假设有多个线程想要操作同一个资源对象,我们首先想到的是使用互斥锁,但是互斥锁是悲观的

悲观,即操作系统会悲观的认为如果不严格同步线程调用,那么一定会产生异常,所以互斥锁会将资源锁定,只供一个线程使用,而阻塞其他线程。

但如果大部分操作是读操作,就没必要在每次调用时锁定资源,或者是同步代码块的执行耗时远远小于线程切换的耗时,这就本末倒置。

因此,我们在一些情况下,不想让操作系统那么悲观,不想过度使用互斥锁。思考是否可以不对共享资源进行锁定,也能对线程的调用进行协调?--->引出CAS

CAS(compare and swap比较然后交换)

举例

假设资源对象为女神,手中的牌子正面为0,反面为1,0表示今天有空,并且表示谁先约到就和谁先共进晚餐,1表示没空。

现有线程A和线程B,且牌子为0;此时A线程先抢到时间片(女神)并将牌子改为1,线程B虽然也到了,但是已经发现牌子状态被改变,只好遵守规则。

当资源状态为0的一瞬间,AB线程都读到了,并且认为当前资源对象的状态值为0,此时它们会各自产生两个值old value(代表读到的资源对象的状态值)new value(代表期望将资源对象状态值更新为想要的值),此时读到的状态值old value为0,new value为1(因为自己把值改为1,就表示已经约上了)

两个线程都去争抢,如果线程A抢到了时间片,将old value与资源对象的状态值进行compare比较发现一致,于是将牌子(状态值)swap为new value,线程B慢了一步,比较发现状态值已经被改为了1,和old value不一致,放弃swap操作 。

但是我们并不会让线程B直接放弃,而是使其自旋(即不断地重试CAS操作) ,并且会配置自旋次数防止死循环,如果在自旋的过程中发现牌子状态值变成了0,则会再次去争抢约会机会,如果线程B耐心耗尽(配置的自旋次数),则会放弃,不再打扰。

代码实现非常简单,但是可以发现并没有进行同步操作,说明线程还是不安全的,是否会出现线程AB同时获得资源,三个人约会?如果想解决同步问题,还是要加锁吗?

答案是,各种不同架构的CPU都提供了指令级别的CAS原子操作,CPU已经原生的支持了CAS

通过CAS实现同步,不会锁定资源,而且当某一个线程需要修改共享的资源对象时,总是会乐观的认为其状态值没有被其他线程修改过(即不会出现同时抢占资源的情况),而是每次都是由自己去compare状态值。

虽然该机制称为乐观锁,但并不恰当,因为并没有用到锁,而是无锁的同步机制


http://www.mrgr.cn/news/53205.html

相关文章:

  • “两马”荣获上全球富豪榜,中国首富成谜
  • 百度智能云千帆 ModelBuilder 大模型服务及开发解读
  • SpringBoot使用SqlSessionFactory方式配置多数据源
  • python中的WEEKNUM(ISO周数获取)
  • Oracle 使用位图索引 Cost降低200倍! 探讨位图索引的利与弊
  • 传感器黑电平箝位(Sensor black level clamping)
  • Python 处理命令行参数
  • Java 后端开发面试题及其答案
  • HTTP/HTTPS
  • 【数据结构与算法】插入排序、希尔排序
  • Oracle T5-2 ILOM配置
  • 存在重复元素 II
  • HarmonyOS NEXT和认证(在校生的大福利)
  • Pycharm下载安装教程(详细步骤)+汉化设置教程
  • 基于SSM+微信小程序的电子点餐管理系统(点餐1)
  • 【YOLO学习】YOLOv5详解
  • 【第三版 系统集成项目管理工程师】第18章 职业道德规范
  • 力扣力扣力:一文搞定前序遍历的所有方法!
  • 使用kimi编辑助手,开始搭建一个微信小程序!第一天
  • Cisco软件基础使用