乐观锁和悲观锁

举报
dfsafdfsaf 发表于 2021/05/11 23:43:08 2021/05/11
【摘要】 常见的锁的类型:偏向锁、自旋锁、轻量级锁、重量级锁、独占锁、共享锁、公平锁、非公平锁、可重入锁、读写锁。乐观锁vs悲观锁:乐观锁和悲观锁只是设计思想上的一个概念。乐观锁:假设认为数据一般情况下不会产生并发冲突,所以在数据提交的时候才会去对数据检查是否发生了并发冲突。(即在同一时间点只有一个线程对共享变量操作,所以适合乐观的思想)乐观锁的问题:并不总是能处理所有问题,所以会引入一定的系统复杂度...

常见的锁的类型:

偏向锁、自旋锁、轻量级锁、重量级锁、独占锁、共享锁、公平锁、非公平锁、可重入锁、读写锁。

乐观锁vs悲观锁:
乐观锁和悲观锁只是设计思想上的一个概念。
乐观锁:假设认为数据一般情况下不会产生并发冲突,所以在数据提交的时候才会去对数据检查是否发生了并发冲突。(即在同一时间点只有一个线程对共享变量操作,所以适合乐观的思想)
乐观锁的问题:并不总是能处理所有问题,所以会引入一定的系统复杂度。

悲观锁:总是假设最坏的情况,每次别人拿数据时都会产生并发冲突,都会去上锁。(思想:同一时间点,经常有多个线程对共享变量操作,适合悲观锁)
悲观锁的问题:总是需要竞争锁,进而导致发生线程切换,挂起其他线程;所以性能不高。

所以要使用哪种设计思想,应该根据不用的应用场景来决定。
基于乐观锁实现的机制:CAS机制,又称无锁操作;
CAS: Compare And Swap ,比较并交换
CAS(V,O,N)——>V:内存地址实际存放的实际值;O:预期的旧值; N:要赋值的新值。

可能出现的问题:ABA问题
CAS(V,O,N)中,当V==O时,N可以直接写进V;当N!=O时,不能写入,但当O ==N时,也可能时已经被其他线程修改过,但预期的旧值还是等于主存当时存的值,这就是ABA问题。
解决方案:增加版本号;
作用:每次修改后,版本号+1,通过版本号来观察V是否被修改过。

总结:

1.悲观锁是线程先加锁,后修改变量操作;
2.乐观锁是线程直接尝试修改变量操作,在这个过程中不会发生线程阻塞;
3. CAS的实现原理:基于unsafe来实现,本质上是基于CPU提供的接口保证线程安全修改变量;
4. CAS在java中的应用:
自旋锁:
无条件自旋
有条件自旋:如可中断的自旋(自旋时可以使用线程判断中断标志位后再执行)
自旋+CAS的适用场景:同一时间点,常常只有一个线程操作。
不适用的场景:同一时间点,常常有很多线程操作。
自旋的缺陷:线程一直处于运行状态,占用CPU内存,比较耗费资源。

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。