Compare And Swap

- 它将内存位置的内容与给定值进行比较,只有在相同的情况下,将该内存位置的内容修改为新的给定值。 这是作为单个原子操作完成的。 原子性保证新值基于最新信息计算,如果该值在同一时间被另一个线程更新,则写入将失败。
- 原子性的保证
通过比较操作:
- 如果两者相等,则表示没有其它线程对当前内存的值进行修改,那么此时就可以把新值存入该内存地址中;
- 如果两者不相等,则说明有其他线程在线程Ⅰ执行期间抢先对该内存地址的数据进行了修改,此时线程Ⅰ的执行就算失败了
- 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 区别
1万+

被折叠的 条评论
为什么被折叠?



