『凯哥Java』Java多线程并发之读写锁
Java多线程并发之读写锁
本文主要内容:读写锁的理论;通过生活中例子来理解读写锁;读写锁的代码演示;读写锁总结 。 通过理论(总结)-例子-代码-然后再次总结 , 这四个步骤来让大家对读写锁的深刻理解 。
本篇是《凯哥(凯哥Java:kagejava)并发编程学习》系列之《Lock系列》教程的第七篇:《Java并发包下锁学习第七篇:读写锁》 。
一:读写锁的理论
什么是读写锁?
多个线程同时读一个资源类是没有任何问题的 , 所以为了满足在并发的情况下 , 读取共享资源应该是可以同时进行的;但是 , 如果一个线程想要去写共享资源 , 就不应该再有其他线程可以对该共享资源进行读或者是写操作了 。
即读写锁在同一时刻可以允许多个多线程访问 , 但是在写线程访问的时候 , 所有的读线程和其他写线程都会被阻塞 。 读写锁实际维护了一对锁 , 一个读锁 , 一个写锁 , 通过分离读锁和写锁 , 使得其并发性比独占式锁(排他锁)有了很大的提升 。
为什么需要读写锁?
通过前面文章的学习 , 我们知道了ReentrantLock(下文简称:RLock)对象了 。 Rlock比起synchronized(下文简称Sync)来说有三个优点:RLock可以被中断;RLock可以有公平锁;RLock可以绑定多个条件 。 那么既然RLock比Sync有这么多优点 , 为什么还需要读写锁呢?
那是因为RLock是独占式(排他)锁 , 即当线程1获取到资源的时候 , 其他线程不能再来操作共享资源了 。 就算是RLock的操作是读取的时候 , 其他线程也不能读取共享资源的操作 。 这在现实生活中是不符合逻辑的(在下文神话中读写锁的例子中我们就能体会到为什么不符合逻辑的) , 而且性能也比较慢 。 所以就有了读写锁的出现 。
二:读写锁的理解
生活中读写锁的例子
例子一:我们大家去火车站乘车的时候 , 有个大大的公示屏幕 , 会告诉大家当前车次是否晚点 。 显示屏是给给所有乘客看的 , 如果火车晚点 , 对应车次后面就会被修改成晚点大约xxx分钟 。 这个修改的动作只能是火车站内部人员来操作的 , 我们乘客是不能操作的 。 这个过程 , 站在并发角度来分析的的话:电子屏幕是共享数据;千千万万的乘客是不同的线程;火车站内部工作人员也是不同的线程;乘客是读资源的线程 , 当一个线程来读取的时候 , 其他线程也可以读取操作的;火车站内部工作人员修改火车信息的时候 , 同时只能有一个工作人员来修改 , 不能两个都来修改 。 如果两个都来修改的话 , 上一秒显示晚点1min , 下一秒显示正常 。 这个是不行的 , 乘客有可能会错过乘车的 。 所以修改的时候同时只能由一个工作人员来修改 。
例子二:我们在玩王者荣耀的时候 , 有时候会遇到停服更新的 。 在不更新前 , 所有玩家都可以玩 , 当停服更新的时候 , 所有玩家就不能玩了 。 这个操作在并发角度来说:千千万万的玩家是读共享资源的;游戏维护者是写操作的 。 当停服更新的时候 , 读操作就被阻塞了 , 只能等写操作 , 也就是更新完成后 , 才可以接着玩 。
通过上面两个例子我们可以分析到读写锁的三个参与者:共享资源;读对象;写对象 。 而且读和写一般是分离的 。
三:读写锁的代码演示
我们就用火车站进站案例来模拟:

文章图片
未使用锁的时候
先来看看屏幕对象:

文章图片
再来看看多个工作人员更新操作及多个乘客获取操作:

文章图片
查看运行结果:

推荐阅读
- 『Java』java数据结构系列——什么是数据结构
- 『Java』马云:成功人跟普通人差不多,但这三点我一定要分享给所有年轻人
- #Java#java线程到底有多少种状态?
- #智能手表#1、初识java-1
- [华为]有朋友问我“JAVA全栈”、“互联网架构师”和“JAVAEE”到底是什么?
- 「javascript」这边走Javascript了解一下
- 「华为」一篇有趣的Java class
- struts@Java面试之项目面试问题——不看面试会后悔的
- IT之家R9 3900,12核心24线程,吾空空妖X5笔记本发布:搭载AMD
- 「Java」六面蚂蚁金服,唬住了面试官要了30K;其实Java面试也没那么难
