CAS概念梳理

Compare And Swap



在这里插入图片描述

  • 它将内存位置的内容与给定值进行比较,只有在相同的情况下,将该内存位置的内容修改为新的给定值。 这是作为单个原子操作完成的。 原子性保证新值基于最新信息计算,如果该值在同一时间被另一个线程更新,则写入将失败。
  • 原子性的保证

    通过比较操作:
  1. 如果两者相等,则表示没有其它线程对当前内存的值进行修改,那么此时就可以把新值存入该内存地址中;
  2. 如果两者不相等,则说明有其他线程在线程Ⅰ执行期间抢先对该内存地址的数据进行了修改,此时线程Ⅰ的执行就算失败了
  • ABA问题
    假设线程Ⅰ尝试使用CAS将变量的值从A修改为B,那么当CAS通过内存偏移获取了变量的值后在比较操作之前线程Ⅱ通过CAS将同一内存位置变量的值从A变为B再变回A后,比较操作仍然为A=A,此时值相等但不是一个A,此时仍然可以设置为B。
  • ABA问题的解决
    通过引入时间戳,可以区分两个值相等的A

Compare And Set

  • 一种理解是compareAndSet的api,内部调用了CAS原子操作
  • 还有一种是在数据库中,为了解决并发的库存扣减

库存业务,stock(sid, num),其中:
sid为库存id;num为库存值

在这里插入图片描述
如上图所示,两个并发的查询库存操作,同时从数据库都得到了库存是5。
接下来用户发生了并发的库存扣减动作:
在这里插入图片描述
这两个设置库存的接口并发执行,库存会先变成2,再变成3,导致数据不一致;

实际卖出了5件商品,但库存只扣减了2,最后一次设置库存会覆盖和掩盖前一次并发操作

大家常说的“Compare And Set”(CAS),是一种常见的降低读写锁冲突,保证数据一致性的乐观锁机制。

  • 针对上述库存扣减的例子,CAS升级很容易,将库存设置接口执行的SQL:
update stock set num=$num_new where sid=$sid

升级为:

update stock set num=$num_new where sid=$sid and num=$num_old
  • 为了解决数据库中的ABA问题,即使用带版本号的乐观锁
    旧版本“值”比对CAS
update stock set num=$num_new where sid=$sid and num=$num_old

升级为“版本号”比对CAS

update stock set num=$num_new, version=$version_new where sid=$sid and version=$version_old

参考

什么是CAS?CAS的ABA问题,ABA问题会导致什么后果?
java CAS compareAndSet, compareAndSwap 区别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值