前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在ReadWriteLock类中读锁为什么不能升级为写锁?

在ReadWriteLock类中读锁为什么不能升级为写锁?

作者头像
我是攻城师
发布2018-08-03 11:00:47
2.7K0
发布2018-08-03 11:00:47
举报
文章被收录于专栏:我是攻城师我是攻城师

上篇文章中已经介绍过在Java并发包里面的读写锁

代码语言:javascript
复制
ReadWriteLock lock=new ReentrantReadWriteLock();

读写锁的最大功能在于读共享写独占,从而在读多写少的场景下能够提升并发性能。

关于读写锁里面有一个锁升级和降级的问题,也就是写锁可以降级为读锁,但是读锁却不能升级为写锁。那么为什么是这样?

其实也不难理解,只要线程获取写锁,那么这一刻只有这一个线程可以在临界区操作,它自己写完的东西,自己的是可以看见的,所以写锁降级为读锁是非常自然的一种行为,并且几乎没有任何性能影响,但是反过来就不一定行的通了,因为读锁是共享的,也就是说同一时刻有大量的读线程都在临界区读取资源,如果可以允许读锁升级为写锁,这里面就涉及一个很大的竞争问题,所有的读锁都会去竞争写锁,这样以来必然引起巨大的抢占,这是非常复杂的,因为如果竞争写锁失败,那么这些线程该如何处理?是继续还原成读锁状态,还是升级为竞争写锁状态?这一点是不好处理的,所以Java的api为了让语义更加清晰,所以只支持写锁降级为读锁,不支持读锁升级为写锁。

举个生活中的例子,在一个演唱会中,台上有一名歌手在唱歌,我们可以理解为它是写锁,只有他在唱歌,同时台下有很多观众在听歌,观众也就是读锁,现在假如歌手唱完了,它可以立马到台下很轻松的就降级为一名观众,但是反过来我们宣布一项规定,谁先登上舞台上,谁就是歌手可以演唱一首歌并获得奖金,如果真的是这样,那么所有人必然会蜂拥而上,这时候就乱了,弄不好还会出现踩踏事故,所以观众升级为歌手这件事情代价是比较大的。

这就是读锁为什么不能直接升级写锁的主要原因,当然这里并不是绝对,升级写锁的最佳条件是一次只允许一个读线程升级,这样以来就不会产生大量不可控的竞争,在JDK8中新增的StampedLock类就可以比较优雅的完成这件事,这个到后面我们再分析。

关于读写锁升级和降级的示例代码,我已经上传到我的github上,感兴趣的同学可以下载和学习,这里由于篇幅原因,就不在贴出了。

https://github.com/qindongliang/Java-Note

参考链接:

https://stackoverflow.com/questions/33342593/why-isnt-readwritelock-upgrade-allowed

https://blog.takipi.com/java-8-stampedlocks-vs-readwritelocks-and-synchronized/

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-07-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 我是攻城师 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档