悲观锁和乐观锁_多线程并发之乐观锁和悲观锁

2ddca8b161c61a337ac4e75649a33b5b.png

多线程并发是高级程序员进阶绕不过去的一道坎,在大用户应用的场景下,并发是必然存在的。

很多人人都知道遇到并发要用锁,但是会用锁和用好锁是两回事,只要你真正理解锁的意义,才能更好地发挥锁的价值。

首先,我们理解一下一道常见的面试题,什么是悲观锁和乐观锁?

悲观锁,为了防止自己拿到数据后别人会来修改,你就把数据加上锁,直到自己处理完,才会把数据释放给别人。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。

乐观锁,在拿到数据后,不会立即进行数据锁定,只有等到数据需要更新时,才会判断数据是否和那到时一致。

两种锁的应用场景,取决于业务类型,如果是多线程对数据的抢夺比较严重的,那就只能用悲观锁,如果大家对数据的抢夺比较少,偶发的,那么从提高效率的角度来说,可以使用乐观锁。通常涉及到写入数据比较频繁的,用悲观锁比较多,如果是读取比较多的,可以用乐观锁。

乐观锁的实现机制

1、版本号机制,数据有相应的版本来进行确保一致性。

例子:比如A和B同时从数据库获得了数据Money100,这个数据100对应了一个数据版本1,此时A要扣50(100-50),B要扣60(100-60)。B最先提交给了数据库,在提交的时候确认了当前数据库的版本号依旧为1,于是就写入了数据(100-60)剩下40,同时更新了数据版本2。此时A操作完了,也准备写入数据库,本来(100-50)是可以操作成功的,但是A在写入时发现,数据版本变成了2,于是从新从数据库拿到了剩余的数据40,然后再扣款就失败了。

2、CAS算法(compare and swap),无锁编程,在线程没有阻塞的情况下实现变量的同步。CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。其基本原理等同于版本号机制,旧的预期值等于数据版本,如果在进行原子操作时,发现旧的预期值和当前的内存值V不相等,则取消操作,否则把B值赋值给内存V。

乐观锁的问题

乐观锁会带来无限循环问题,也就是俗称的ABA问题的,因为在确认版本数据的同时,很有可能数据再次发生了修改,而程序已经默认为没有修改,这样就会出现漏洞。其次,在最坏情况下,循环检测的乐观锁的开销可以无限大,影响CPU的开销。

下一篇主要讲一下悲观锁synchronized的使用和底层实现机制

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值