栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java并发(十三):读写锁之间的锁降级和锁升级

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java并发(十三):读写锁之间的锁降级和锁升级

    • 回顾
    • 锁降级
    • 锁降级的必要性
    • 锁升级

回顾

之前已经分析了读写锁之间是如何进行加锁的,下面就看看,读写锁之间怎么进行锁降级与锁升级的

锁降级

读写锁的锁降级指的是写锁降级成为了读锁

当一个线程获取了写锁,并且又获取了读锁(获取写锁的线程可以获取读锁),那么当该线程释放了写锁时,该线程拥有的锁就会进行降级,变为了读锁,其实这个实现从之前看加锁源码就知道了,读锁和写锁的获取都是分开的,所以写锁的释放不会影响到读锁的持有

锁降级的必要性

锁降级的情景是,拿了写锁,然后再拿读锁,这有什么必要性吗?拿了写锁我就进行修改了,写锁已经限制了别人进行访问和修改了,我要读锁来干什么呢?

我觉得这个必要性是看场景的,只有当线程既需要写操作又需要读操作的时候,锁降级才有必要性

一般我们用锁进行操作数据时,都是下面三步

  • 获取锁
  • 操作数据
  • 释放锁

假如一个线程对某个数据进行先写后读操作,那么操作顺序一般变成下面所示

  • 获取写锁
  • 修改数据
  • 释放写锁
  • 获取读锁
  • 访问数据
  • 释放读锁

那么此时问题就出来了,在该线程释放写锁的一瞬间,就会有其他线程去获取写锁,那么该线程就会获取读锁失败,并且在线程在等待自旋获取读锁中,那么,当其他线程修改完数据并且释放了写锁,该线程再去获取读锁进行访问,就会出现无法感知其他线程对数据的修改状况出现

比如说,线程A获取写锁将变量修改成了5,然后释放了写锁,其他线程去获取写锁将变量修改成了6,线程A再获取了读锁进行访问变量,得到的结果为6,出现了幻觉一样,这就是没有感知到其他线程对数据修改,也就是幻读

所以,建议是获取了写锁之后,假如后续还要对数据进行访问,一定要获取读锁再释放写锁,拿到的读锁会限制写锁的获取

当然,可能会有人觉得,拿到了写锁之后,直接完成所有的读写操作再释放写锁不就好了吗?

这样做也是可以避免幻读产生的,但是逻辑不符合现实,并且效率会降低

  • 做完对应的操作就应该释放对应的锁,这是正确的逻辑,就好像上课去签到一样,只有一张签到表和一只笔,你签完名就应该放下笔让别人签,而不是为了看看班上有几个女生的名字而不放下笔,应该放下笔,在旁边看
  • 降低了效率,对于一些只读的线程,当前线程已经修改完了,就应该立刻释放写锁,让其他线程可以获取读锁来进行访问
锁升级

读写锁不支持锁升级。。。。。。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/328022.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号