悲观锁和乐观锁

悲观锁:比较悲观,认为线程安全问题一定会发生,因此在操作数据之前先获取锁,确保线程串行执行。-例如Synchronized、Lock都属于悲观锁。

乐观锁:比较乐观,认为线程安全问题不一定会发生,因此不加锁。只是在更新数据时去判断此期间有没有其它线程对这个数据做过修改。(其实依靠了数据库的锁)如果没有修改则认为是安全的,自己才更新数据。如果已经被其它线程修改说明发生了安全问题,此时可以重试或异常。

问题:乐观锁怎么知道在自己要更新数据,别的线程在此期间有没有对数据做了修改?
乐观锁的关键是判断之前查询得到的数据是否被修改过。
1.版本号法:
在基于数据库表的版本解决方案中,通常为数据库表增加一个“version”字段来记录数据的版本。
当读取数据时,会将当前的版本号一同读出;在更新数据时,会对版本号加一,并将其与数据库表对应记录的当前版本信息进行比较.(set version=version+1 where version=1)
在这里插入图片描述
在这里插入图片描述
2.CAS法(Compare and Set)
此方法是在版本号法的基础上进行了简化,版本号法判断数据是否被修改看得是version.而CAS法用要被修改的字段代替了version。这里以stock(库存)为例,先查询库存数,在修改的时候判断库存数是否和之前查询到的一致,一致就修改。

在这里插入图片描述
在这里插入图片描述

乐观锁的弊端:
假设一开始有10个线程都查询到了stock(库存)为100,但只有一个线程能执行修改操作把stock改为99,其他线程都会执行失败,这样看来乐观锁的失败率太高了,用户动不动就秒杀失败。。
这里因为是库存,即时数据变化了,也无所谓,优化为stock>0就可以了,所以即时数据在此期间被修改了,我们也可以修改。但有些情况下,这里的字段不是库存,我们必须通过数据在此期间有没有被修改过来判断,这种情况字段>0就行不通了。

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值