00:00
同学们大家好,我们继续通过上一节读写所的意义和特点,我们大致了解了可重复的读写所主要是一题两面,读写互斥,读读共存。好那么接下来咱们加写代码来证明它的功能和特点,这是第一个问题。第二个问题,我们写的时候不会只关写它,我们也得说一下各种的演化怎么推到我们的第四个邮戳所,它的由来怎么个演变推进出来的?好,那么重点邪所饥饿所见即是本篇章的核心内容,好啊,因为源码呢,大家都清楚。说穿了还是一个什么aqs啊,这个我们已经大规模的讲过,一般问aqs啊,不会牵扯到读写锁,但是一问到读写所,必然而然会牵扯到我们的所饥饿和所降级两个问题,以及。为什么会推出邮戳锁?好,咱们呢,先完成第一步,从无锁到洛接口,再到。
01:08
读写锁的接口,它是如何一步步演变的,给大家说清楚来。代码说话,走起。我们都明白,可重入读写所。首先可重入第二个。一体两面对吧,要么切黄瓜,要么拍大蒜,选一个吧,所以说读写坚固,那么来吧,它的演变是这么来的。我们呢,先提前写好哔哩哔哩读写锁这个包里面。我们模拟自己做一个简单的缓存。My resource是资源类模拟一个简单的缓存的一个封装体。缓存底子主要就是map,那么接下来这个是lock接口。典型的实现类可重入锁,这个是读写lock,典型的实现类是可重入的读写锁。好。一个个来,一般缓存最经典的有两个方法,不是读就是写啊,当然还有缓存超时清空啊,那些我们就不写了,不在我们的本次讨论范围以内,我们主要是给大家介绍可重入的读写所,那么来吧,Public。
02:13
Void。那么string key。Value。最经典的对吧。那么来吧。首先。对于高并发多线程,100%的要访问某个资源内肯定要加锁,所以说无所重视,我们就不介绍了,这个是完全是浪费大家时间,那么我们就给大家演示和验证。为什么要从二。到三,为什么要从三再到四?好,先说二。那么下面呢,我们先讲我们以前了解过的lock。那么TRY。Look。Look look OK,那这个时候我们大家请看。正在写入没问题吧?那么现在哪个线程进来正在写?你们写什么呢?map.put t。
03:05
Value没问题吧?OK,那么为了给大家演示效果好看一点,我们的。也别一窝蜂的过来模拟呢,500毫秒0.5秒写一个,那么写完以后。搁到这儿,那么这个就是什么。完成写入,那么这个的意意思和方法,这个方法的意思是什么呢?假设线程一进来,一正在写的时候,这是个什么锁?现在这个lock是不是一个?独占锁,独占就是排他,那么有有点类似于什么这个线程呢?持有锁,他正在写入的时候,没有写完的情况下,别人不可以和他抢,因为写索是独占和排他的,好这是我们的写方法,那接下来。我们的读方法。来,同学们。各位亲老,和刚才一样。
04:02
写完了我们就得读。那么。来吧,这个呢,就是正在。读取。OK,好,那么来吧,map.get t。Value。那么这呢,我们呢。也呢?给他停顿一下,模拟有点业务,那假设写的话要500毫秒,那么诶。读的话呢。200,那么相当于说同学们可以得到一个结论,什么读是不是要比写要快好?那么这我们待会儿要给大家验证一个没写完的时候允不允许读。第二个没读完的时候可不可以写?好,第三一个再来看看。读写是否互斥?读读是否可以共存来?那么接下来呢,我们呢?还这么回事儿。那么。完成。
05:01
读取。欧了。葛亲。看一眼很简单吧,一个是写,一个是读,接下来。来吧,老规矩。线程操纵资源类。一来咱们呢,就是。十个线程O吧,那么这个线程呢,十个线程我们要有点资源嘛,先得写,往缓存里面写入。那么这个时候。OK,那么相当于说T就是一二三四五六七八九十,值也是一二三四五六七八九十,那么这样一一对应的上,那么这由于是拉姆达表达式定义变量的时候要变成这样,OK,那么来同学们这是什么?十个线程来写,那么接下来你也晓得的自然而然是不是十个线程来读啊,好的。和上面一样,那么接下来我们就来看看现在这个锁是什么锁,Lock是不是就是以前我们讲过的,那么这些都给大家写清楚过了,我们呢?不废话,我们先从第二个情况给大家进行介绍和演示,来,同学们先来看看程序写的对不对。
06:10
等它运行好起来,后台效果大家请看一正在写入完成写入二五六七八九十等等等等,没有任何问题对吧?那么下面我们可以看得出,现在一正在写入二。正在写入五六九十,无所谓,线程是各种排气和交替的,那么大家可以看得出我们这儿得到的效果是什么。任何一个线程正在写的时候不允许被打断,好,下面请看三,三正在读取,三正在读的时候,别人可不可以进来,也不可以,那么我们这儿互相交替以后,得到一个演示的效果。如果是洛,由于我写,我故意把时间写的很多,读故意把时间搞得很短,那么有可能某个线程去读的时候,他还没有写完呢,所以说它读取的十个,那这个没有任何问题,接下来我们可以看得出。
07:11
永远出现的都是成双成对的。一正在写的时候,别人也不可以来读,也不可以来写,也就是说在一跟一之间不可以加三。O吧,那么所以说不管你怎么写,怎么读,无所谓,总之一句话,一定是正在。要等它完成,接下来另外一个线程才能干,所以说在洛这块的时候,我们会发现多线程过来,不管是读还是写,每次都是一个only one,因为它是什么。Lock即可,反正卫生间的门栓进去以后,不管你是什么样一种形式的方便,每次啊只能一个,我们这儿要说的,不是说这读到难啊,这个不重要。重要的是,不管是写入,正在写入还是完成写入,你看仅仅配对中间不允许加三好,那么同学们,我们呢,再来看一下。
08:05
这个时候大家请看啊。请看。这个这种情况下而言,是不是。一到十写入写入二一对一,一对三,一对四,一对五,七九六八十没问题吧,我正在写的时候读。不允许。如果说正在读的时候,那么也是什么一一匹配,并且也不允许别人加三,而且写也加入不进来刚才第一次的案例,对吧?那么因为多线程每次跑的案例它是不一样的,所以说这个呢,大家不用怀疑,OK,所以说我们得到这儿可以看得出控没控制住,绝对控制住了,因为这个不是开玩笑的,这是啥洛克对不对?那么所以说这种情况下,每次只放进来一个。理论证明成功,但是它不好的地方我们大家都清楚,读写写,读写写,只要沾写的时候有且仅有一个,可不可以,完全可以,所以说什么叫只有一个,就是说假设这个正在。
09:08
写弱,那么他没写完的时候,别的线程不能够加进来。控没控制住,精确性、一致性绝对OK,但是非常抱歉它的并发性和可读性性能是不是下降。因为我们希望。读写互斥是应该的,但是读读我们是希望是可以共享的,所以说各位同学,我们这儿可以看得出,读读的时候一正在读的时候一没有读完。不可以获得写,更不可能有其他读跟我一起进来读,这就麻烦了,那比如说我们电影院一个屏幕在正前方。播放源有且仅有一个,相当于写操作,但是读取的时候,我们当然希望能够并发读取,就是一正在读的时候,二也可以进来读,四也可以进来读,六也可以进来读,对吧?所以说为了解决这个问题,我们才引入了我们的一体两面的读写所对写。
10:04
独占,对读、共享,这就是它出现的意义和价值。那么来,同学们请看一体两面过来,这你得写清楚是读所还是写锁,相当于这把菜刀,是切黄瓜还是拍大蒜,选一个,所以说在这块斜我们就是斜锁,那么在这块,那么弟兄们晓得的,我们呢,就是什么毒所好。请看,还是熟悉的配方,还是熟悉的味道。我们的程序没有变,只是把锁变了。我们现在想达到的效果是什么?写100%只能独占写的时候。不可以有人中断加三,但是读的时候我们希望某一个线程正在读取的时候,别人也可以进来读,达到共享读这样的一种效果。来同学们,现在我们。折腾完了以后换开。来,同学们请看。正在写的时候没有任何一个人可以打断,但是大家请看,我们换成读写组的时候,一正在读的时候怎么着,是不是二也可以进来,三也可以进来,六也可以进来,八也可以进来。那么一。
11:11
正在读的时候,你看到这儿是一读完,但是在一在读取之间,是允许其他其他线程能够刷进来的,所以说这个就变成了对于写我们另独占一个,但是对于读可以有多个,达到了共享的目的。完成了我们的要求和效果,就是多线程并发,可以访问。大面积的可以容许多个线程来读取,那么读多写少的时候,读写索的性能是非常good并优秀的。OK,好,这个呢,我们就证明了。我们的一体两面,读写互斥,读读是共享的,好,那么接下来最后一个知识点,我们这暂停呢是。200毫秒,那么这个呢,是刚才的,那么现在。
12:01
我把这段呢,直接。改吧,改吧。加时间。暂停2000毫秒干什么?演示。读写所,它的要求,也就是说读所没有完成。之前。邪索无法获得。这一波能不能理解?请大家思考一下我们读写所的另外一个意义和要求,他想达到的效果是什么概念呢?那么。就是说我们要演示一体两面,读写互斥。读读共享做到了,在这儿我故意把时间搞的呢,读要花更多的时间,那么这是不是已经先写完,先写完了,是不是已经先示范了写索了?没错吧,但是这儿还没读完呢,读的比较慢,也就是说读没有完成的时候,写索无法获得,OK。
13:06
读所没有完成的,没有完成之前,写索无法获得要演示我们的第二种情况,那这是啥意思呢?跟这个一样,那么同学们请看啊,那么假设我这停一秒钟故意的啊,没什么,呃,特殊的意义,那么现在我过来这儿。又来三个新的什么写线程?OK。和刚才一样。啥意思呢?那么现在一到三,也就是我有三个新的写线程,我又想去写,一秒钟以后这三个是不是就应该。启动了,但是别忘了前面有十个写。每个要占0.5秒。后面呢,还有十个读,每个要占两秒,我这儿要演示的意思就是先写。
14:01
在读,但是读所没有完成之前写所无法获得,那么在这儿同学们请看。这个就是新协所OK县城。来吧。这有三个没问题吧,三个新协锁线程123,这个没问题,那么。一秒钟以后,我要准备启动了,我要去抢锁啊,但是在我前面有个谁有十个线程在读,那么我们要给大家演示啊,读锁没有完成的时候,写索是无法获得的。OK,读没有完成的时候,写索无法获得。来,同学们请看演示效果跑一下。第一组。我现在写正在写,正在写,无所谓,OK,好。不允许加三,但是请看正在读什么概念。一正在读。三正在读的时候,只要你没读完无所谓,读读可以共享,但是大家请看123正在写入啥意思啊?上面的读没有读取完成的时候,新的写锁线程,想来强索的时候抢不到,因为上面的读没有完成的时候,写索无法获得。
15:19
好,我们再给大家演示一下,第一组正在写,挨个挨个。来正在读,每个读两秒钟,你看他没有读完的时候,新写索线程,123这三个是拿不到我们的读所的,所以说这个就是我们的案例给大家做了演示和结论。一体两面。读写互斥,读是可以共享的,但是读没有完成的时候,其他的线程想获得写索是无法获得的,那么同学们刚才可以看得出。来写的时候独占排他,有且仅有一个,所以说紧挨着,但是读的时候,比如说一正在读,二也可以进来,三也可以进来读,是共享的,但是没有。
16:09
读完之前非常抱歉,后面的写锁拿不到,OK,所以说结论就是我们红色框框这一个,那么这个就是我们读写所从落到。瑞德特洛可充的读写所,它出现的意义,那么解决了什么?读读只有一个的这种不好的情况。读写是互斥,读读一定要可以共享。
我来说两句