我对乐观锁CAS的知识回顾

乐观锁

每当提起乐观锁,都会被提起CAS。对于乐观锁,是系统一种比较乐观的状态,认为线程中运行时大概率不会产生资源竞争的情况,因此不会运行的时候就开始获取锁,只有等到有资源竞争的时候才会获取锁,Java中一般通过CAS机制来解决。
书面上的话:比较并交换(Compare And Swap),主要是为了解决原子性问题,同时又不想利用重量级的锁。通俗的话说:如果想更新一个值,想看看该值是否等于某个值,如果等于则更新该值。
我可以简单举一个例子:
在这里插入图片描述

CAS主要是为了解决原子性问题,CAS为什么可以保证原子性呢?

CAS本身通过本地(native)方法来调用,该类可以直接操作底层内存的数据,Unsafe中所有的方法都是用native修饰,可以直接调用操作系统底层资源执行任务。其中变量valueOffset表示该对象值在内存中的偏移地址,用来寻找数据的地址。
在这里插入图片描述
面试题:既然CAS就可以解决原子性问题,那是不是可以这么说并发编程中可以不需要synchronized或者ReentrantLock了?是不是对象的原子性保证用CAS就够了。
不是的。因此CAS本身也有很多缺点。最显著的有三个缺点:

  1. 循环开销大:如果比较的时候一直不等于预期值,则会一直循环等待,直到比较成功为止,该过程会给CPU带来较大开销。
  2. 只能保证一个共享变量的原子操作。对于多个共享变量无法保证原子性,因为每次比较的都是一个元素。
  3. ABA问题

大名顶顶ABA问题

所谓ABA问题,比如数值i = 5,A线程本来想改成10,在更改之前,B线程先将i先由5变成了6,再更新成5,但是A线程并不知道i发生过改变,仍然将i改成10。尽管最后的结果没有问题,但是整个过程还是不对的。
在这里插入图片描述
解决ABA问题!重点!
可以采用AtomicStampedReference来解决,因为在这个API中,加入了一个变量版本号,每执行一次这个方法,版本号+1。每次执行需要检查当前版本号是否和期望版本号一致。
在这里插入图片描述

其实我对CAS的理解就是一种思想,比如在我的超卖项目中,我曾经使用过数据库层面解决过超卖问题,也就是给数据库字段添加一个版本号或时间戳,当下次执行sql语句的时候会带着版本号一起查询,每当添加或修改一次数据库都对版本号进行+1。完全可以解决超卖问题,只是对数据库的压力很大!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值