java车次信息_从火车站车次公示栏来学Java读写锁

Java多线程并发之读写锁

本文主要内容:读写锁的理论;通过生活中例子来理解读写锁;读写锁的代码演示;读写锁总结。通过理论(总结)-例子-代码-然后再次总结,这四个步骤来让大家对读写锁的深刻理解。

本篇是《凯哥(凯哥Java:kagejava)并发编程学习》系列之《Lock系列》教程的第七篇:《Java并发包下锁学习第七篇:读写锁》。

一:读写锁的理论

什么是读写锁?

多个线程同时读一个资源类是没有任何问题的,所以为了满足在并发的情况下,读取共享资源应该是可以同时进行的;但是,如果一个线程想要去写共享资源,就不应该再有其他线程可以对该共享资源进行读或者是写操作了。

即读写锁在同一时刻可以允许多个多线程访问,但是在写线程访问的时候,所有的读线程和其他写线程都会被阻塞。读写锁实际维护了一对锁,一个读锁,一个写锁,通过分离读锁和写锁,使得其并发性比独占式锁(排他锁)有了很大的提升。

为什么需要读写锁?

通过前面文章的学习,我们知道了ReentrantLock(下文简称:RLock)对象了。Rlock比起synchronized(下文简称Sync)来说有三个优点:RLock可以被中断;RLock可以有公平锁;RLock可以绑定多个条件。那么既然RLock比Sync有这么多优点,为什么还需要读写锁呢?

那是因为RLock是独占式(排他) 锁,即当线程1获取到资源的时候,其他线程不能再来操作共享资源了。就算是RLock的操作是读取的时候,其他线程也不能读取共享资源的操作。这在现实生活中是不符合逻辑的(在下文神话中读写锁的例子中我们就能体会到为什么不符合逻辑的),而且性能也比较慢。所以就有了读写锁的出现。

二:读写锁的理解

生活中读写锁的例子

例子一:我们大家去火车站乘车的时候,有个大大的公示屏幕,会告诉大家当前车次是否晚点。显示屏是给给所有乘客看的,如果火车晚点,对应车次后面就会被修改成晚点大约xxx分钟。这个修改的动作只能是火车站内部人员来操作的,我们乘客是不能操作的。这个过程,站在并发角度来分析的的话:电子屏幕是共享数据;千千万万的乘客是不同的线程;火车站内部工作人员也是不同的线程;乘客是读资源的线程,当一个线程来读取的时候,其他线程也可以读取操作的;火车站内部工作人员修改火车信息的时候,同时只能有一个工作人员来修改,不能两个都来修改。如果两个都来修改的话,上一秒显示晚点1min,下一秒显示正常。这个是不行的,乘客有可能会错过乘车的。所以修改的时候同时只能由一个工作人员来修改。

例子二:我们在玩王者荣耀的时候,有时候会遇到停服更新的。在不更新前,所有玩家都可以玩,当停服更新的时候,所有玩家就不能玩了。这个操作在并发角度来说:千千万万的玩家是读共享资源的;游戏维护者是写操作的。当停服更新的时候,读操作就被阻塞了,只能等写操作,也就是更新完成后,才可以接着玩。

通过上面两个例子我们可以分析到读写锁的三个参与者:共享资源;读对象;写对象。而且读和写一般是分离的。

三:读写锁的代码演示

我们就用火车站进站案例来模拟:

bf995fa8e4f45008b7abb5e22df394a2.png

未使用锁的时候

先来看看屏幕对象:

a62bdbf88a0e52d50dc285fa57d8b7c0.png

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

6e1ff98c7277c2babbe655278e96586f.png

查看运行结果:

c6a49514f1f48992bde6b55549bff045.png

从运行结果中,我们可以发现当工号未13的还没有更新完车次信息的时候,工号12和14的员工也来更新了。这种操作是不允许的。因为写操作要原子性,要独占。当工作人员甲在修改的时候车次信息的时候,其他工作人员不能同时修改同一个车次信息了。而且从乘客获取车次信息的数据来看,获取到的只是工号是13的。这个时候获取到的数据不一定是正确的了。所以,不使用锁是不行的。

使用排他锁

如果使用独占式做的话,我们查看运行结果:

0f3be53bb4c0f3ed132b2277baa06de6.png

从运行结果来看,再读取的时候,需要一个一个读取的。当16号乘客查看的时候,17号乘客是不能查看的。这个是不符合实际业务逻辑的。所以,独占式(排他锁)RLock在这里不适合。我们再来看看读写锁:

使用读写锁

先来看看使用读写锁的屏幕对象

de47875a9c735fd1bcf8b7ec6044a692.png

再来看看运行结果:

bef93a3a75ff3bc3103c0d26ec0c4591.png

从运行结果中,我们可以看到,工作人员是一个一个的操作完成的。当14号操作完成之后,13号和12号才可以操作的。这个符号我们正常的业务。乘客读取的时候,读取到的都是最后一次更新,这个也符合我们的业务。所以,通过读写锁来操作车站屏幕是可以的。

b8c00fd46f37ce39440201f0b1e9aed8.png

四:读写锁总结

4.1:wrLock类对象

7672b42b4c9bb9945fec81ae74e94e9f.png

同样包含了公平锁和非公平锁。

其中ReadLock是读锁对象;WriteLock是写锁对象。

4.2:使用语法

读操作使用ReadLock

a72a66c8c01184c4ced0569ddef11787.png

编辑

写操作的时候,使用WriteLock对象:

c27b87a3196dc5988f051cc709c33ea0.png

4.3:总结

读写锁(ReentrantReadWriteLock),凯哥就简写rwLock。也可以实现公平和非公平的。其内部维护了一对锁:一个读锁(ReadLock对象),一个写锁(writeLock对象),通过读写分离的方式来提高并发性能。读写锁也叫共享锁。其共享是在读数据的时候,可以让多个线程同时进行读操作的。在写的时候具有排他性,其他读或者写操作都要被阻塞。

一般情况下,读写锁的性能都会比排他锁性能好,那是因为,大多数场景读操作多于写操作的。在读多与写的场景下,读写锁能够提供比排他锁更好的并性能和吞吐量。

wx.jpg

​    ​    ​    ​    ​    ​    ​    ​    ​    ​    ​    ​    ​    ​    ​欢迎来聊~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/442577.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java构建xml参数_Java中使用XML创建EMAIL模板

邮件模板让我们来看看邮件模板的格式。模板是XML文件,它包含一个根元素和一系列根的子元素。根元素是。必要的子元素是, , 和 。可选的子元素是 , , 和 。如果你使用过邮件系统,那么你可以推导出这些元素实际包含的内容。可选的元素有多个实例&#xff0…

java 多目录 编译jar_javac编译多个包下的、依赖其他jar包的java文件

问题:多个*.java文件编译*.java文件依赖其他的jar包如下文件结构:F:\jar_prachild--child01--MyChild.java--child02--MyChild.javaparent--MyParent.javaMyParent.javapackage parent;public class MyParent{public void show(){System.out.println(&qu…

java11创建项目_2019-04-11 使用IDEA创建SpringBoot项目

一. 使用IDEA新建项目根据需要选择starter这样使用IDEA搭建的一个SpringBoot项目就可以了。同样可以通过https://start.spring.io/构建。二. 结构分析1.Springboot01Application:运行Springboot01Application就可以启动Spring Boot工程。2. pom.xml中则配置好了选中的starter的…

微博php sdk,php sdk微博第三方授权登入简单使用

简单说一下OAuth协议:OAUTH是一种开放的协议,为桌面、手机或web应用提供了一种简单的,标准的方式去访问需要用户授权的API服务。下面我们去微博开发者平台登入微博。如图填写信息:网站接入->创建新应用填写信息后可以拿到微博给…

php xml数据拼接,在PHP中合并XML文件

我有2个文件,1.xml并且2.xml两个文件的结构相似,我想拥有一个。我尝试了许多解决方案,但只有错误-坦白地说,我不知道这些脚本是如何工作的。1.xml:1Title 1Author 1...2.xml:190Title 190Author 190...我想…

java中document解析jsp,JSP基于dom解析xml实例详解

本文实例讲述了JSP基于dom解析xml的方法。分享给大家供大家参考,具体如下:初次学习用dom操作xml文件,有很多不足之处,牛人多给点建议,练习时我没对中文做乱码处理,也没做验证哦!O(∩_∩)O~实体类…

php导出excel不完整,急:php导出excel时,因数据比较多,经常导出不完整就结束了【php系统数据导出excel表格】...

急:php导出excel时,因数据比较多,经常导出不完整就结束了设置超在服务器上设置也可以,在当前文件写代码也可以服务器上找到php安装下的php.ini找到max_execution_time这句,将值改为你想要的时间,或者该为0表…

php禁用eval,zp blog

最新版的suhosin需要php版本大于5.4,对于5.4以下版本则需要安装补丁,尴尬之处在于安装补丁需要重新编译PHP并安装…… 总感觉莫名的不好干货:1、suhosin-0.9.36版本可以支持PHP5.3 且不用安装补丁2、安装步骤wget https://download.suhosin.…

php 堵塞 消息队列,PHP的并发处理

PHP如何处理并发什么是进程、线程、协程进程 Process计算机中的程序关于某数据集合上的一次运行活动,“一个执行中的程序”系统进行资源分配和调度的基本单位三态模型:多道程序系统中,进程在处理器上交替运行,状态不断地发生变化运…

php中节点值怎么获取,php – 节点更新:获取旧值

我正在使用nodeapi更新更新节点,但是我需要在幕后进行更多操作,这需要我知道字段的旧值/是否有一种方法可以在覆盖之前获取字段的旧值. 最佳答案 编辑hook_nodeapi()只对新的$node对象起作用,所以我之前的回答对你没用.相反,您需要在提交时访问节点.为此,您需要注册自己的提交处…

php 购物车封装代码,PHP中封装Redis购物车功能

// 服务层namespace Common\Service;use Vendor\Func\Red;class CartService extends CommonService {protected $redis;protected $pre_key;public function __construct(){parent::__construct();$this->redis Red::create();$this->pre_key C(USER.CART).C(APPID).:…

matlab pca和逆pca函数,matlab_PCA,训练集与测试集分开,原理和用法

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼PCA基本流程:1、训练集矩阵算协方差矩阵A;2、算协方差矩阵特征值与特征向量;3、按特征值的大小排列特征矩阵,得B,对应的特征值(按从大到小排列)组成向量a;4、A*B得到去关联的新矩阵C,…

w3cschool php 调整图片尺寸,PHP_php修改上传图片尺寸的方法,本文实例讲述了php修改上传图 - phpStudy...

php修改上传图片尺寸的方法本文实例讲述了php修改上传图片尺寸的方法。分享给大家供大家参考。具体实现方法如下:// This is the temporary file created by PHP$uploadedfile $_FILES[uploadfile][tmp_name];// Create an Image from it so we can do the resize$…

matlab频域低通滤波程序,低通频域滤波器在Matlab中的设计与实现.pdf

低通频域滤波器在Matlab中的设计与实现’ … … … … … ’ ’实用第一..智‘‘慧密集. . . . . . . . … … . . . … &…

matlab做比例积分微分控制,PID控制器的微积分分析matlab代码

PID 控制器由比例环节(Proportional)、积分环节(Integral )和微分环节(Differential )组成,连续PID 控制器的一般形式:dt de K d e K t e K t u D tI p )()()()()(0τττ? 一、比例控制及性能分析比例控制器的传递函数为:p p K s G )( 例题…

php引用对象方法吗,在PHP中引用容器对象的方法?

您必须修改代码才能提供关系.在OOP中,我们称之为aggregation.假设PHP 4,以及“一系列条形图”的想法class foo {var $bars array();function __construct() {"Foo Exists!";}function magic_bullet($id) {switch($id) {case 1:echo "There is no spoon! "…

数据合并计算php,各位大神,求助如果用VBA实现以下数据合并以及数量计算

Option ExplicitModuleName"模块1"Dim aData, dic As Object, aResSub start()Dim i&, n&, aTmp, minNum, maxNumDim spNum&, strData, id, numaData Range("a1").CurrentRegionSet dic CreateObject("Scripting.Dictionary")For …

python执行文件函数,python如何运行函数

运行Python的函数,只需要调用函数名,在传递参数就可以,不必关心函数体内部的代码块。函数是带名字的代码块,用于完成具体的工作需要在程序中多次执行同一项任务时,你无需反复编写完成该任务的代码,而只需调…

php小白书,php小白的自学第一天

虽然我还没有学会Python,但是已经开学了……然后老师要验收以php编写的网页……(wdnmd )这两天先把这个网页设计处理了,Python也会学,Linux还没开始,web更是啥也不会……谁再和我说大学比高中轻松我跟他拼命(听说只要先熟悉了HTML…

linux配置文件为yum,yum的配置文件说明

1、网上的可供yum的链接,要求里面有repodata目录,该目录就是分析 RPM 软体后所产生的软体属性相依资料放置处。2、配置文件:/etc/yum.repos.d/CentOS-Base.repo,也可以此目录下建别的以.repo后缀的文件就行[base]:代表…