乐观锁和悲观锁

共 1240字,需浏览 3分钟

 ·

2021-03-28 10:12

点击上方蓝色字体,选择“标星公众号”

优质文章,第一时间送达

 在多线程场景中,为了保证线程安全,因此需要对线程加锁,除了使用synchronized关键字外,还有许多的锁机制。

常见的锁的类型:

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


乐观锁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内存,比较耗费资源。

————————————————

版权声明:本文为CSDN博主「AI小艾」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:

https://blog.csdn.net/m0_46551861/article/details/115058433





粉丝福利:Java从入门到入土学习路线图

👇👇👇

👆长按上方微信二维码 2 秒


感谢点赞支持下哈 

浏览 22
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报