00:00
下面呢,我们呢就来尝试写一下我们的洛support,当然啊,它就不需要这些锁块了,这是它的第一个优势,好,那么同学们,我们呢,代码说话先来看看,还是和刚才一样啊。我们呢,直接走起,这个是我们的A线程,好,由于啊look support这呢它。在我们的唤醒安帕克方法这,它要传一个参数线程进去,相当于说你给哪个线程唤醒,你给哪个线程唤醒,那么这个时候我们呢,所以说在这的定义和变化呢,我给它呢,稍微改一下啊,那么这就是a.start相当于说A线程我们呢起到。跟前面之前的内容呢,是一样的啊同学们,我这儿呢就。Come in a线程是不是进来了,进来完了以后啊,在这的话呢,我是不是就是被唤醒。那么以前我们都知道我们要写一个什么SYNCH锁块是吗?是不是洛克UN洛克等等没有了。
01:03
直接look support.park听懂,这个就是我们之前的所讲过的类似于我们的wait方法,在这块的时候它就直接怎么着被。阻塞了,那么等待通知。OK。等待通知二或者是什么?等待放行好吧,那么现在呢,是只要这个park就是什么,他要通过。他要通过。需要许可证。那么现在我A线程的许可证就要由B线程来发放,相当于是由B线程来唤醒他,通知他,好,那么同学们。我们这儿呢。Sleep,这就是三秒钟,OK吧,三秒钟以后,我们的B线程现在能够启动了,那这是B线程,这是B线程,这是B线程,好,和刚才的是一样的啊。
02:04
同学们,三秒钟以后B线程运行,那么现在B线程要去唤行A,相当于说要给A发放许可证,A才能够被放行,被唤醒。好,那落。support.IPA大家请看它是不是要传一个现成的引用变量进去,所以说我这把它定义成这样一种模式,A,那么你B唤醒谁呀?B唤醒A,那么这个时候。就是我们所说的什么东东,那么是不是发出。通知了,这么样的一个东风啊,这么样一个信号,好,那么同学们请看,完全没有锁块,直接就是第一个优势就是不需要锁块,不用跟那些什么snchize lock混淆在一块,我就想单纯的堵塞一下线程,咱们拿通行证说话好跑一组。大家请看,A进来了,三秒钟以后。第一通知了,诶被唤醒了怎么样,和前面的效果是不是一模一样,它这个时候大家能不能理解洛克after运用了之后它的强大功能呢?我只想单纯的阻塞唤醒线程,并不想用你那么复杂的。
03:15
这些套路还要SYNCH,还要落,必须要在锁块里面,我不需要,OK,好,那么接下来同学们,我们待会先把功能级别的演示完成,我们再说源码和底层的原理,那么第二个知识啊。我们继续,如以前,我们都是wait notify先。等待后被唤醒,那么现在我们也看到了先帕后安帕,这个顺序是不是也是OK的?那么我们反其道而行之啊,现在我要求先安帕。再看看会不会报错。那么现在呢,我们就把这个。提到上面,那么同学们都清楚啊,这个就很简单了,对吧,相当于说B线程先通知啊。
04:02
好了,B线程就结束了,三秒钟以后A线程才去。运行,那么看看这个park还有没有作用。好,同学们。你们猜一下它能不能解决这个问题。走起漏,现在是B先通知了,还没有被阻塞呢,先通知了怎么着A进来了,A怎么样被唤醒,所以说呢,他呢,直截了当的一句话就是说,如果你先安帕A了,这个A里面就算有一个帕,没有任何作用,相当于这行代码被注释掉了,这么说。能理解,形同虚设,这一行代码根本就不起作用,如果你要是不相信啊,同学们,我们呢,来一个system点。Current。咱们来打出它的毫秒数。如果这个park起作用了,这两个时在这儿,如果它起作用就是没有被屏蔽,那么这个时候开始时间和结束时间是不是不应该一样啊?那么下面我们再来玩一次,大家请看B通知了,三秒钟以后,A我们来看看他的尾号怎么着。
05:11
20458 20458告诉我尾号一样,说明这一行几乎等价于什么,根本就没有起作用,被注掉,OK,所以说我们得到洛克的第二个功能。安帕。可以在帕之前执行,那是是不是比以前的强大,我们的通知可以在阻塞之前执行,这个时候先通知了,这个阻塞没有任何意义了,OK,所以说它的功能非常的强大,那么同学们。我们来看看正常和无锁块的要求,刚才已经演示了下面之前错误的先唤醒后等待,就是先notify再wait的话,换以前就是这两个三角形里面的这个套路里面它是报错的,但是到我们的罗以后照样支持。
06:02
不管是先等待后唤醒,还是先唤醒后等待,人家什么全流程OK,全部都支持,所以说呢,请同学们要明白。在这儿我们也看到了。这个呢,跟刚才的演示一样,这个时间戳是不是一样啊,那么park方法就形同虚设,时间是一样的,好,那么接下来。API级别的调用我相信你已经会了,无非就是两个小细节嘛,不需要锁块,然后park安帕还是安帕帕都可以,前后顺序无所谓。API会调用,但是我们不能满足于是个API调用工程师啊,我们得看看底层的源码,进入深度的分析。首先,先来看。帕克底层是个啥?安C类掉了安C类的帕克方法,那么这传的两个参数,那么这个时候同学们我们再点开过去看,一个布尔,一个浪琴,那这个时候它是什么意思呢?走起。来。归根结底,它是一个现成的阻塞工具类。
07:02
所有的方法都是静态方法,这一波能跟上洛克吗?他们不用尿。可以让线程在任意位置阻塞,阻塞之后当然也应该有对应的唤醒方法,归根结底,Support调的是UN shift类当中的是吧,Native方法兄弟们没问题吧?所以说它底层是靠C语言的原语级别这样来控制的,这是第一个,第二个啊,我们不妨呢再来看看它的流程啊。它提供了帕安帕来实现线程的阻塞和唤醒每个罗support。和每个使用它的线程都有一个许可证。请看官网站是不是说除非许可证听懂?这个许可证就叫permit,相当于一零的开关,默认是零,调用一次安帕克就让它从零加一就变成一,相当于说安帕克就是给这个县城放行发放一个许可证。调用一次帕就会消,就会消费掉一个许可证,将一又变回了零,同时帕就立刻返回了这个方法,那么如果再次调用帕克又会变成阻塞能跟上。因为。
08:11
一张证只能用一次明白。直到他们。无效维持,所以说我们现在呢,再调用安帕克,又会把这个PERMIT1是为一,因为安帕就是发,发放通行证帕就是消耗通行证,简单的来说,每一个线程都有一个相关的permit,最多只有几个,一个重复调用安帕也不会累计凭证,为什么?官网上我们一开始的时候是不是给大家说过这么一句话,请看。Permit permit许可证是不可以累积的,最高的峰值上限是多少?图案,所以说呢,把这个意思我们这儿讲清楚以后,不妨我们再回到这儿做做实验。好,同学们。我们在这儿呢。
09:00
直接呢,给他回归。正常的,好理解啊。我这儿同学们。再来一个。Park这一波能跟上,那么这我们再来一个啊,Park那么来看看啊。我这是不是相当于发了两张站。如果从字面意思,从代码上,但是你告诉我。请看。B通知了三秒钟以后,A能不能被解锁。你看下面是不是一直没有打出来,为什么呀?UN帕克的累计值啊,几次啊,最高时间你调多次安帕克不可以累加,不是又发了一个站,又发了一个站两个站,而是最多几个most one只有一个,所以说一个站对清一个park方法,第二个帕克方法,它就被什么阻塞了。OK,所以说这块要明白,那么我们继续。回到我们的理论说明,我们形象的来理解,就是说线程阻塞需要消耗凭证,Permit这个许可证最多只有几个,一个单调用park方法时,如果有凭证,那么则会直接消耗掉这个凭证,正常退出,如果没有凭证,就必须阻塞,等待凭证可用。我们一开始第一个帕的时候,他有没有通行证,没有谁调谁就阻塞,直到别人给我安帕来给我放行。
10:25
而安帕克相反,它会增加一个凭证,但是每次你就知道,我们凭证发放的话,最多只能有一个累加,无效明白,所以说这就是他的什么原理,底层要看。它是按A类支持底层原理,就是我们的permit许可证,来,同学们请看,只要这个线程不为空,那么是不是安帕给当前这个线程解锁,给当前这个,给当前这个线程唤醒,给当前这个线程发放permit许可证?好。那么从这。我们呢,就得到了我们的洛斯类帕克安帕克方法的详细的讲解,那么它呢,功能呢非常强大,那么来看看我们最后的面试题。
11:09
为什么可以先唤醒线程后阻塞线程?因为安帕克获得一个凭证之后,再去调用帕方法的话,就可以名正言顺的凭证消费,不会阻塞,所以说它跟顺序无关,跟锁块要求无关。第二个为什么唤醒两次后,阻塞两次后最终结果还会阻塞现场这块就是一个面试题,因为它的最高就是我们一再强调,我都带着大家看过官网了干嘛。是不是there is at most one许可的累加上限就是一正安park就是一,不可以累加好,那么所以说同学们,这道面试题我们也讲清楚,凭证的数量最多是一连续,你别说两次,多次调用也不会累加,明白连续调用两次和调用一次安帕克效果都是一样,只会增加一个凭证,而调用两次安帕却要消费掉两个凭证。
12:02
两个车只有一个通行证,所以说证不够不能放行,OK,好,同学们,这个就是我们洛克斯的相关的讲解。
我来说两句