00:00
好,同学们,我们继续上一讲,我们明白了,Look support。它的定义是这样让大家记得两个方法,Park。IPA类似于我们的wait notify。好了,回到我们的学习手册。前两个我们大概回答了是什么,他能干些什么?不用下载对吧,怎么玩?那么现在至少得到一个东道,你只需要干park park。那么这个问题怎么给同学们讲清楚呢?跟着我走。下面。我们来看看现成的等待唤醒机制,Wait和notify。还是那句话,先看。Before。以前。那么如果熟悉杨哥的。勾UC的课程,我画过两个三角形。还记不记得这个懂不懂,那么以前的时候啊,同学们,我们说过。这个时候叫SYNCH。
01:01
没问题吧,然后在这儿是不是我们说过一个东西叫wait,我们在这儿是不是说个东西叫notify,这是第一个三角形,那么第二个三角形,同学们也清楚这个时候我们干了一件什么事,是不是有一种东西叫。Look这一波能跟上,它就跟think对标,然后在这儿的时候,我们用condition对象,是不是有个东西叫awake,然后在这儿是有个signal。还有印象吧,同学们,原来我们讲过OUC的基本功,基本基础课的时候,在零基础就业班的时候就画过这么两个三角形,那么现在你告诉我。明明以前比before用这个现成的等待和唤醒机制,Wait和notify wait和signal用的好好的,怎么现在又横空出世整了一个新的类叫洛克support呢?那么这个就是杨哥一直在进行启发式、推导式教学的一种方法。
02:00
我不但要让你明白是什么,更要明白为什么,而不是拿着一堆API乱去调用,没有任何意义。那么现在我们一定要明白,既然人家新推了,一定有洛克support比前面更强大和更牛逼的地方,那么这个就是我们after,有了它之后,我们能获得什么样的好处。明说了,再次强调,所谓的罗support就是线程等待唤醒机制的加强改良版,功能更牛逼,更强大。好,那么同学们。走起。开高。我们来复习。三种让线程等待和唤醒的方法,那么其实已经给大家呢画了这个图了,好。来,请同学们稍微记忆一下。第一个使用object类中的wait方法,让现场等待notify唤醒。Goc包里面的condition是等待,Signal是唤醒,那么第三种就是我们多克阻塞当前线程以及唤醒指定被阻塞的线程。那么这句话来自于哪?是不是几乎就是这句话的原源好?
03:09
他用的方法,那么听着提前说,就是我们下面的什么park相当于wait。安帕相当于notify,也就是什么该阻塞阻塞,该唤醒唤醒。那么又回到这张图,套路上已经有两个了,你还不嫌多啊,为什么要整出来第三个呢?什么叫support呢?它的独到和巧妙,强大的地方,改良的地方在哪呢?下面代码说话,走起,兄弟们。我们先来复习,挨个挨个的带着大家对比。首先,先来看object类当中wait计算方法实现现成的等待和唤醒,它有一些什么样的要求和背景知识。那么来。在这块,同学们。跟着我走。第一波我们先来用用我们的最传统的,那么好啊。
04:05
Object object lock,那么谁持有这把锁,谁呢,就进来,那么现在呢,没方法,主线程只是一个启动的接口,OK吧,那么来同学们,我们现在呢?过来第一个线程。这个线程是我们的A线程,没有任何问题吧?那么来synchize的。Object lock。咱们跑到这儿,同学们都清楚啊,如果我加锁乘高,那么。Current。直接过来。哈密。这块我是不是就进来了,没有任何问题吧,好说明明我A线程进来了,那么A线程我进来了以后,我们最经典最简单的,我马上干嘛胃套好有异常我们把它包起来。都起,那么这样的话呢,我们的A线程完活很简单啊,放心,我不会浪费大家时间,给大家再讲一下什么snch wait和notify,不是现在的重点啊,我都清楚,大家基本上是两年工作经验,一两年工作经验了,我们先用最简单的案例说清楚我们的知识点。
05:12
好,这个是我们的B线程,那么也和刚才一样,Synch object。那么跑到这儿,如果完了以后,我们在这用object.lock我们这儿实行一个什么是不是计。那么好。在这块和刚才一样。那么干嘛?准备或者说。唤醒动作。这一波OK吧,那么同学们你都清楚啊,如果这个是A线程进来了,它是什么,他们那么打出来A进来了,然后马上是不是被。阻塞,那么在这儿我们呢?直接。过来。
06:03
那我们下面呢,为了给大家。更好的看一下这个效果。那么这是不是叫?被唤醒,OK或者这块呢,就是什么呢。通知啊,那更清晰一些,那么现在是不是B通知了A通coming in,然后在这儿可能会被阻塞一下,对吧,然后呢,被唤醒,那么来同学们,我们呢,直接跑一组来看看它的效果。这个呢,都不用我多废话,那么同学们呢,不言自明,一眼就能看穿是吧,基本上就是A进来了,然后B通知A要起床了,A被唤醒,挺和谐的,这个就是我们正常的等待唤醒机制,这一波OK吧。但是。有两个细节跟着我来。第一个。我现在第一个问题。这是我们最经典最朴素的wait wait和notify,好吧。我的问题是一。
07:01
我干坏事。我把这个给注掉。八。没有任何问题吧?请看现在语法根本就没有报错,我的问题是wait和notify可不可以脱离size代码块能够单独的运行?那么同学们请判断一下,我暂停一下录屏,好,同学们,我们呢,直接呢走起,那么下面我们跑一下,看看会出什么样的情况。A确实是进来了,但是。A线程有异常不合法的模exception,那么再来一个,又出了一个东西,一个是34行,一个是24行,那么来同学们请看24。是咱们的什么A个模块,那么34是咱们的什么B这个模块,那么我们得到一个结论就是说。如果不在同一个代码块里面,那非常抱歉,Wait和notify是不可以用的,有点类似于这个铁三角,你不可以破坏,这是第一个知识点。
08:10
第二个有没有发现我们一开口,我们都会跟你说的是wait和notify OK吧,那下面我们的问题是。我把它恢复。刚才正确顺利的程序就是我们先wait后notify,没有任何问题,现在去跑的话,同学们都清楚A进来了,然后。哎,睡了一会儿。被wait了,那B去通知啊,A被唤醒,好说,那下面我们的问题是,如果我现在先执行了notify,然后再执行wait这个程序还可不可以?换句话说,就是。以前我们是wait notify,先wait,后notify,现在我们反过来干坏事,先notify,再wait,那么你们觉得这个程序还能不能正常的运行?
09:04
好,那么一边思考一边看我编代码。那么SLEEP3秒钟,这个A1进来,我就先暂停三秒钟没问题吧,那A在这暂停,这注意,那么现在我们是不是先让B先走啊?好,我们来看看三秒钟以后。这个能不能被唤醒?B能不能走好,那么同学们,我们呢,跑一下。B是不是通知了?一秒两秒三秒,哎,抗议了。但是非常抱歉,因为B通知完了以后,它是不是就释放这把锁了,三秒钟以后,A线程是不是马上抢到这把锁往前走,往前走就打出了我们的coming in a确实是coming in启动了。但是非常抱歉同学们。第30行的。被唤醒这句话有没有被打印出来?没有说明什么?
10:01
A线程是不是一直在这为他被阻塞,因为唤醒的东西已经提前跑到它前面了,在这儿对它无效,所以说没有人把我从wait状态唤醒,这个A线程就一直在这卡着,请看灯没有灭。那么从这我们可以得到了我们第一种方法wait和notify实现现成的等待和唤醒的机制啊。第一种,那么同学们我们要明白wait方法和no t方法两个都去掉同步代码块的话,有没有异常情况,100%有异常报什么,这两个刚才是不是见见到过了,所以说我们在这儿的时候。两个都去掉同步块的话,会看到线程,不管是一和二。都不用废话了,得到我们的结论,不管是一还是二,A还是B,都是这样不合法的。Monitor state exception。结论。
11:00
Wait no five。必须在代码块里面内部执行,必须要用到关键字,有这个限制,这是第一点。第二个我们来看一下。将notify放在wait方法前面,程序无法执行,无法换行,那么这同学们,我们都清楚。错误。没有办法结束行,Notify。这个胃没有人唤醒,所以说。等待中的线程一定要先wait后notify,等待中的线程才会被唤醒,否则无法驱动。那么我们得到的第一个知识点的结论就是,Wait和notify的方法必须要在同步块或者方法里面且成对出现。先喂它。再notify顺序搞反了不OK,那么所以说这个是我们的两个小限制。复习了一下。我们object类当中的wait。
我来说两句