00:00
刚才呢,我们已经看了rise的。底层原理里面的对象初始化,那么这个对象初始化初始化呀,但主要是初始化两个对象,一个是interprise m这样的一个对象。那么然后呢,在这个内部呀,还有一个呢,啊,是我们的lock啊这样一个对象。那么这个对象的话呢,咱们也可以呢,给它放在啊我们的啊这个地方。那么啊,咱这两个对象里面啊,然后在初始化的过程中啊,主要是初始化的一些属性,那比如说在interr MU里面,我们主要是初始化了这样两个属性,一个是BI斯帕的一个玩意。那pass pass呀,就是我们啊初始化,初始化所实啊指定的那样的一个路径啊,指定的节点路径啊,节点节点路径,它将来会作为啊这样的一个by pass的一个使用,也就是我们的定节点的一个使用。
01:00
好,那么然后呢,我们在这个内部呀,又初始化了一个啊叫local这样一个对象,那么它就好能叫这个属性啊,咱可以呢,给它放在这个地方啊,它上的是一个lock啊,这个对象啊对象。那么将来呢,不管是我们加锁,那么还是去解锁啊,那大部分时候呢,咱都通过这个对象那么来去完成的。好,那我们,嗯,再看这个local里面他们干什么事情。在它这个里面呢,我们主要也是初始化的一些属性,那比如说呢,我们这个,嗯,比较重要的属性啊,就是这个马克斯啊利斯。那么麦克斯利斯啊,这个东西呢啊,它是我们这个主约对吧,主约。呃,最大阻约嘛,那默认值它里面传了一个值啊,值上的值是唯一的啊,是唯一。那么然后呢,我们再来看,还有呢,它也有一个best pass,那么这个best pass呀,和我们上面这个best pass是同一个pass啊,值是一样的。
02:08
那么然后呢,我们再来看还有这个pass,那pass的话呢,它是等于啥呢?等于我们的这个指定的这个base斯帕,那么加上一个。斜杠啊,可以加上,加上你可以认为加上一个斜杠还是lock啊杠这样的啊,加了一个中华线,哎,加上这样的一个路径。好,那我们,呃,这样的话呢,初始化方法看完之后呀,我们再来看看加锁的方法啊,怎么加锁的。好,那我们紧接着看看这个加锁怎么加锁啊,咱进入下一个端点直接走。那么然后呢,我们来进入这行代码,呃,Que方法干了什么呢?那掉了这样有一个这样的一个东西啊,Into the lock这样一个玩意。好,那么这个玩意呢,咱们来进去看一下,F7进去啊,啊,进去之后呢,我们来去看一下啊,这这就是那个internal lock这样的一个方法。
03:05
那么因特那个方法,它首先呢,会获取我们的当前线程。那么然后呢,会取当前线程之后呀,它会通过这个瑞的data啊,让后通过当前线程获取一个lock data这个对象,那么three data什么东西呢?哎,我们可以点进去看一下这个S啊,它其实是interpret MU里面的一个属性啊,什么类型的属性呢?是can开呢哈西麦夫这样的一个属性。啊,是这样的一个结构的一个属性啊,咱可以把这个东西呢啊拷贝过来,让它放在这个地方,因为在这个inter MU里面还有一个非常重要的属性啊,就这个死于的data塔这个玩意儿了,那么这个里面主要记录了什么东西呢?主要是记录了这个重入信息啊重录信息。啊,可重复的信息。好,那么来看一下,嗯,它会以我们的线程作为K。
04:00
啊,当前线程作为K,以look data作为value,那么look data有什么东西呢?它是一个静态的内部类,在这个地方呢?那么在静态内部类里面啊,啊有几有这么几个属性啊,哎,是哪个线程的。啊,线程是哪个线程,它会记录线程对象。那么还会记录呢,这个锁路径啊,是哪个哪个锁的重入信息。它会记住这所路径,那么同时的话呢,还会去记录咱们这个lock count,你重入了几次,它都是一个原子操作对象啊啊这的原子操对象。那么所以的话呢,咱之前我们在一测试可从的时候呀,如果我在这个子方法里面又拗了一个所对象,它会怎么样呢。我同一个线程就会远了,就会有多个这个所路径了呢啊。那么呢,之前那个呢,就会被覆盖掉。被覆盖掉,所以的话呢,最终我们的程序呢,就会在那里刷刷刷刷不下去。
05:02
啊,因为呢,咱那个锁呀,啊,它就被覆盖掉了啊,这是很重要的一个信息啊。那我们啊,这个地方呢,主要是它里面有一个lock data,那么lock data呢,它是一个内部类。OK,那么是一个拉。那是lock data,那么这个lock data里面呢,有这么几个属性啊,有我们的这个。啊,是哪个线程的对吧,有这个线程对象啊线程对象。那么还有呢,是咱们这个,呃,Pass。我们是每个所的重物信息,这些记录就是重复信息嘛。啊,那么以及呢,咱入了几次一个lock count啊,这么几个属性。好,这咱们这样一个东西啊,那么啊,它这个的话呢,底层始终是contain开哈希map可以记录啊宠物信息的,而我们之前的话呢,始终是s local啊,但是不管哪种方式,那么都是可以的啊,你只要能够记录下来就可以了。
06:03
好,咱们继续回到那个断点那个位置啊,看咱继续啊往下看啊直接呢往下走,也通过这个当前线程对象,那就获取这个log data,那这个重复信息,如果这个log data重复信息为空,说明什么?所以我这个线程之前从来没有获取过锁的呀,是第一次获取锁。那么第一次火炬索他有这个劳德吗?那平均没有啊。那为了通过这个线程肯定就就获取不到。那么此时呢,它就它就等于钠啊,那么等于钠的情况下,那怎么办呢?我们开始走到下面来了。啊,如果你不等于空,如果lock了不等于空,那说明你之前已经获取过锁了,那我们进行重入就可以了,他对我们这个lock count呀,然后进行呢,进行呃,SCCS操作啊CS操作递增一啊递增一。那么然后如果咱这里呢,是第一次获取到锁,他这一块就不会走了,然开始去去走到这边来啊,重新获取一个锁,那么霍取获锁之后啊,一旦霍金锁成功了是吧,那么这个lock pass肯定不为空了,锁路径肯定不为空,他于是呢,开始给我们又一个全新的lock data。
07:14
那么塔,然后把当天线程以及所路径。啊,都给它放到咱们这样的一个嗯,Log data里面去。那么同时呢,还会给咱们这个,呃,还还会给他去put一下的啊put进去啊put进把我们这个当前线程作为K。嗯,然后呢,以我们这个log data对象作为value put到咱这个的哈希map里面去啊。哎,这个new log data里面,Data里面并没有去指定这个重入次数。那么这个方法没有指定那个重复次数啊,它默认几能默认就是一二,你用好之后呀,默认值这个那count重复次数就是一,就第一次获取的时候,它就不需要一次零了啊好,咱们这个这一块啊,这一块。
08:00
一旦你啊之前获取过锁了,我们就直接进行重入就可以了,就不用再去获取了啊。那如果呃,你没有获取过,那我们开始去获取锁,获取过锁之后呢,来记录这个重复信息,此时呢,它会记录是哪个线程的哪个锁,然后呢,重复了几次,默认是一次嘛,此时是一次啊。然后呢,这个记录好之后啊,就成一个柱或解锁成功了,否则呢,就反了一个false或解锁失败啊。那么然后呢,我们来进去看一下这个方法,这个话就很关键了啊,它是在获取锁这个方法,那我们呢,直接F7进去。这这个呢,不是我们想要看的啊,就是那个get a look nood by by是哪一个,是哪个方法呢?是这个方法啊,来进入的啊,那我们要进行这个方法,因为这是里面的啊,Temp put lock这个方法,哎,那我们就会进入。咱们这个呃temple啊,呃temple lock这样一个方法,就是lock Internet里面这个方法啊。也就是说我们加锁的时候,它走的路走的过程是什么样的呢?来看一下,咱记录一下来啊,加锁的时候。
09:04
那么首先呢,我们会走的是呃,Interp process MU里面的这个,呃,Queer方法啊,呃queer这样的一个方法,那么这个亏要方法呢,它又可以去调我们的。啊,因为调我们的这个,我们现在是方法啊,来看一下啊,I是internal lock这个方法,它因为调internal practice MU里面的internal lock这个方法。啊,调自己类里面的lo这个方法,那么然后internallo这个方法呢,它又会去调,嗯,另外一个类的。另外一个类的,然后是呃,Temp temp的,然后是lock这个方法,它会调这个类的啊。这样烙的方法,那么点上。啊,然后呢,是这个吗。
10:00
啊,咱们可以呢,往后面去移一下啊。那么这个方法干了什么事情,我们可以去看一下,直接呢F7进入好进去之后呢,它到这个lock里面去了,到这个类里面去了,啊这里面有这样的一个方法哈,那么上面的话呢,做一系列初始化,那就获取系统当前时间。啊,然后呢,嗯,再去获取我们这个等待时长对吧,咱们可能有一个过期时间的啊。啊,霍金锁的过期时间的。啊,咱们这个等待时间,那么以及呢,再去啊,获取了这样的一个玩意儿,那这个玩意的话,其实没啥意思啊,咱直接过就可以了,让这个重数次数啊重试次数OK,那么以及呢啊,反应定应的一些变量嘛,啊局部变量啊,这些局部变量的话,咱后续也会看到啊。你看这套,咱主要看这个,当这个变量A,当这个变量呢是为false range为false。那为false情况下加一个非就为出啊,它就会一直进行变力,这个有个死循环变力啊,来尝试火炬锁。
11:02
他一在这里进行便力尝试。火炬锁。好,那么然后呢,我们来去走啊A当为false,诶它首先呢,把这个当设置为负。这是尾处。那么如果后续你不把这个当设置为false的话,那这个循环就退出去了,对啊,就退出去了。那么咱的话呢,呃,后续啊,会有地方设置为falses啊,比如说你如果获取锁失败了,呃,获取锁的过程中出现异常了,就获取锁失败了,就把它设为falses,设置为false的情况下,那你这个位置呢,又调进行便利尝试获取锁,那么直到什么时候呢,直到这个位置获取锁成功了。那就可以呢,呃,终止去获取终止循环了啊好,那我们来继续走,因为这边有个our pass,就当前,嗯,咱这个所得所路径啊,当前所路径。那么他通过咱们这样的一个方法来去创建一个当天所的一个节点,当心节点,然后获取当天所的一个全路径。啊,接点的全固定。好,那我们可以进入这个方法去看一下干什么事情,直接F7。
12:00
好在这里面呢,它主要是给我们去定义的一个变量。啊,然后呢,做了一个判断啊,这个判断咱不管他了,不管是走哪个里面啊,它都会走咱们这样的一个这样一行代码,你这样这两行代码几乎是一模一样的。那么这样的话在干什么事情呢?就在创建一个你临时的序列化节点。啊,临时序列化节点。他就在干这个事情。那么这个临时序列舰载路径是什么样的呢?是这个是这个路径吗?好,我们可以进去看一下啊,看看是不是这个路径创建出来的。那如果正常情况下,按照我们以前的理解,它应该是在这个路径后面生成一个序列化节点,然后后面有个序列化号的啊,哎,其实呢,这里呢,没有那么简单啊,咱们可以进入这个呃,Four pass方法里面去看一看,直接F7进去啊,这个呢,不是我们想要看到的那个东西啊,我们要看到那个four pass那个方法好直接呢,我们来走走,这里面都没啥东西啊,直接到F7再进去。好,这也没啥可看的啊,咱就直接啊走就可以了,F7再进去,那主要是看那个four pass方法啊,这个也没啥东西啊,F7进去。
13:07
啊,这也不是。哎,方pass方法,因为方pass方法呀,这个呢,就是一个路径啊,就是我们这样的一个路径啊,就是我们正常来说,应该根据这个路径生成一个节点嘛,序列化节点啊。那么他干了什么事情呢?再夫妻进去。那这不是我们想看的啊,他做的这个方法,刚才啊,那我们来进行这个for pass法,他进了一个重载的for pass方法。那么这个里面呢,他又会去走到哪里去呢?啊,我们来走,你看这的话呢,又获取了一个什么,呃,Just pass一个路径。Just pass这个路径。那么这个路径啊,就是我们真正啊,它是真正的那个路径了啊,大家这种反应结果就是什么东西。它最终返回了一个什么呢?GU lock,然后呢,下划线C下划线,然后后面这是一个UID啊UI。然后再杠上一个什么lock杠,然后后面再给一个序列化号啊,哎,他这么去搞的。
14:05
大家就很神奇对吧,OK,那么咱这个东西呢,其实你也可以去进去看一下啊,它里面呢,做了一些呃,特殊处理,给他拼了一些值在里面,那我们呢啊,进去看一下吧,咱重新打个分离在这个里面啊。我们把这些呢全部放行。一会我们要看的是啊,得just pass这个方法啊,来看看看什么事情啊,实际呢,F9F9我们都已经放行了啊,放行了之后呢,我们这个地方呢,诶是不是还没放行完,直接走走,我们都放行完啊,放行完之后呢,我们来去再去刷新一下。而此时呢,我们只要直接找那个方法就可以了,就这个得加pass,它怎么生成的。好,那我们直接去,嗯,进去啊,这不是我们想要看到的一个方法哈,来,Just pass。啊,这也不是我们想要看到那个方法哈,我们就直接,嗯。走走。奥,对加帕这个方法,哎,已经进来了。
15:01
那么首先的话呢,它这里呢,就是啊,调了这样的一个方法叫pro protected model.do protected这个方法。那么这个方法呢,它会嗯返回什么东西呢,就返回do protect a pro protected这样的一个玩意儿,Orange呢是为false,当我们去初始化这个对象的时候,初始化这个对象的时候,出化这个对象的时候,那它其实呢,就会去初化这个初这个对象的时候呀,这个对象初始化它应该有个导法啊。应该有不当法,嗯,在哪个地方呢。找它的构造方法啊,OK。构造方法。嗯,哎,没有这个挡法吗。应该是有的哈。它里面呢,就会去set这个pro take这个model,然后把它设置为true啊,这为出,呃,前面呢,咱是不是有漏掉什么地方呢,我们来看一下啊嗯。
16:02
这个地方呢,它会设置为处啊上咱就不看了吧,咱就往下走就可以了啊,啊直接走。啊,走到这下面去之后呀,啊,反正这个呢,前面肯定会有一个小小的设置啊,但可能是漏掉哪里遗漏了,但这个呢,不影响大局啊OK,那么这个里面呢,我们来看,嗯,它这里呢,有个ZK pass get pass and no。然后呢,把这个pass给它放进去。放进之后呢,最终返回是一个pass and node,这个pass and no是一个对象,对象里面呢,其实有两个字段,主要是两个字段啊来看一下。啊,这个对象。嗯,这个对象呢,在在这个下面呢,我们可以看一下pass note里面主要有两个字段,第一个是场呢,是pass,那是不是那个best pass嘛,就是我们指定那个根节点路径啊,那么然后呢,还有这个lock name,然后分成这两个东西,它先合在一起,然后又去给我们做拆分,就反正就是呃,这个代码啊,写的很啰嗦,呃,绕过来绕过去的,对吧?给你合并好之后呢,又又给你解开,又给你分装一个缓给你解开。
17:08
那么解开之后呢,然后呢,在这里呢,呃,又去做了一堆处理啊,又做了一堆处理,检他会在我们的这个,呃,在我们这个noe前面,这note不行,那个lock干在note前面,又给你拼一大堆东西,是拼一些前缀。PA前缀,那么这个前缀是什么东西呢?咱可以进去看一下。那直接F7它会返回一件UID,当我们这个对象,当我们这个pro text Mo这个对象,那么初始化的时候,它就会去,它就会去掉。当执行这个方法的时候啊,它不仅把这个值呢设置为true,同时它会调这个re proed ID这样一个东西,那么这个ID呢,就像就是UID给我们是那个UID。其实这个东西呢,应该是当我们项目一启动的时候呀,他就会给我们去生成这样的一个VIP啊。啊,只要你没有重启它的UID呢,啊都是一样的好,那我们呢,来去回过头去看一下啊,最终呢,他给我们返回这样一个UID,我们直接走。
18:10
走到这来之后呢,那么这个UID呢,就给我们加到这个前面去了啊,加到前面去了,好我们直接去。啊,在这走,那么加完之后呀,这个name变成什么样子呢?Name还还有个下划线C呢,哎,我没有出乎意料,还有下划线C呢,刚才我们没有进入这个方法去看一下啊,这下方线C哪里来的好,最终这个下划线C哪里来的呢?给咱拼接的啊,它也是给咱拼接的啊,那么在我们的这个方法里面,他就给我们又拼接了一个这样的玩意儿。那我们可以点进去看一下啊。那么点进去之后呢,你看咱们这个地方呢,加了一个这个东西,这个东西其实是一个常量啊,它只上的只是下网线C下划线。那它在这个里面,咱可以点进去看一下啊,那就是类里面的一个静态的,然后呢,Final类型的啊,常量下划线C下划线。
19:01
好,那我们再回到刚才那个方法里面去,你看它会给我们拼接一个下划线C下划线,然后再加上这个protected的ID,就是那个UID啊。然后再去拼接上一个杠啊,再拼接上一个杠,然后最终的话,再把这个lock杠给拼接到最后面去。啊,那么这个,呃,这个东西呢,是在我们那个。在我们这个外部方法里面来给我们进行拼接的啊,那最终把这个节点呢,把这个给它拼接到最后面去。啊,先处理好这个前缀之后啊,再去拼接上这个lock lock杠这样的一个东西。那么整个序列化节点的前缀啊就搞定了,将来在生成节点的时候呀,它会有一个序列化号在后面啊。好,那么这个pass呢,最终它就处理好了,那处理好之后呢,它就返回了啊,这样的一个啊pass全路径啊,这是根节点,然后这是咱们这个基当前基顶的前缀都已经准备好了。
20:04
那么准备好之后呢,我们来走啊,走到这里来,它就可以获取咱们这个ICUICU权限列表。然后开始去验证啊,验证咱们这些约束,验证我们这个路径啊,看看是不是合法啊,最后一次验证,那么验证完之后呢,反正做了啊,做了一些啊,各种各样的一些验还是验证吧,反正啊然后呢,开始去把这个路径呢反馈出去。那返回出去之后呀,再去走啊,走到这个方pass里面去,那么这个基点呢,它就可以创建成功了啊,走到这里来,它就创建成功了。此时呢,我们就可以看到啊,他在我们这个根节点下面啊,创建了一个以它为前缀的,然后呢,序列号是0000000的啊这样的一个序列化节点。好,那我们啊继续往下去走啊,如果我们这个节点创建失败了,那它会走到太里面去,来进行重试。那么如果出现成功的话啊,那么开始拿到我们这样的一个路径啊,我们直接呢去走下一步,那么一梦达这个路径呢,已经拿到了。
21:09
那么此时来去看一下啊,咱们这个总K客户端里面啊,有没有这样的一个节点,那OK is还是K,然后呢,是locks下面。Lock下面有没有这样一个节点,那我发现没有这样一个节点,那没有这样一个节点,它怎么走呢?好,我们来继续走啊。我们下一步往下走。啊,他说呢,创建出这个节点,但是其实是没有啊,没我们发现没有啊,那没有它怎么处理,再找到下面来了,那找到K里面去了。啊,那么嗯,被捕获到这个异常,捕到这个异常之后呀,那我们这个呢,又会把这个当重新设置为false。那重新设置为false的情况下,那它又会进入我们这个外循环里面去再次给我们创建这个节点。
22:00
因为设置为false了吗?设置为false之后呢,肯定还会去再走这个走这个断点啊,于是再给我们创建一次,那么此时这个节点有没有创建出来呢?我们再来去查看一下啊,来走,因为我们发现呢,已经创建出来了。那拆出来之后呀,那么开始看一下咱有没有锁对吧?啊,哎,能不能回到这个锁,那has the lock有没有这个锁那呢,是为false啊。好,那么然后你再看啊,看这个方法了,就很关键,在它有个internal lock los后面直接呢啊I7进去。那么进去之后呢,呃,在这个里面呢呢,首先呢,回到锁,默认值是false,没有回到锁。那实行删除它呢,也是为false,这有两个标识V啊,你可认为都是false,那么然后呢,我们来走走啊,在这个地方呢,啊,咱这个东西啊,嗯,不用管它啊,不用管它,那开始进行value循环。来去获取我们的客户端状态,是不是已经启动这个状态,如果是启动状态的话,那并且呢,没有获取到锁的情况下。
23:07
没有锁的情况下,他开始走到这里面去了。啊,如果你已经会到锁了,还有要在组里面了,那也就没有必要了啊,他就可以直接去,呃,Reta有这个锁就可以了。啊,有手就可以了,咱们可以走,那么然后在这里面呢,它首先获取一个排好序的。嗯,秋瑞。啊,在获取我们根节点下面的已经排好序的这个蚯蚓列表。好,那么这个呢,大家可以进去看一下,咱先就写过这样的一个东西啊,自己写过他F7进去。啊,那么然后在F7进去了,掉了一个重载方法啊,F7进去。它进去之后呀,根据这个best pass best pass前面就获取过啊,在这个local里面就有这个best pass,它是个全局变量嘛。然后进而呢,就可以获取这样的一个children列表,诶,怎么回事啊,跑到K里面去了。啊,因为呢,他发现这个东西是应该是为空了,是不是啊,然后跑到这个K里面去了啊,然后再一走。
24:06
啊,然后又去获取了一次,此时的话,这个秋瑞呢,市场呢,是这个有没有获取到我们发现呢。他这里呢,就没有获取到秋瑞对吧,或者秋水为空啊,当它应该是当前基点的话呢,应该是呃,没散到里面去啊,应该这么搞的。当然了,不同的客户端它的机制呢可能不一样,他这个应该是没放到里面去。啊,那么啊,秋瑞,然后的话呢,再去,呃,再去获取这个序列化节点,序列化的这个节点。它会从我们这个,呃,它会从我们这个整个这个路径里面啊,来截取我们的序列化节点。把从这个base pass加一这个位置加一这个下表开始截取,截取到最后嘛,对吧?啊,然后截取我们这个序列化节点,序列化节点不就是下划线C下划线,然后呢,跟上这样的一个东西嘛。
25:00
那当前这个虚拟化节点已经拿到了。那拿到之后呢,来看啊,他开始去,嗯,Guess the pass,通过抓一表,Get the pass。那么这个抓表的前面呢,没怎么说过它啊啊,它这里面是调这个方法,那这个方法呢,其实也不复杂啊,就是判断啊,我们当前这个序列化节点在这个区位里面是不是最小的对不对啊,如果是最小的不就获取所成功了吗。它会返回这样的一个结果啊,如果不是最小的,那它会返回,呃,这个要监控的那个那个基点路径,那这个对象里面其实就两个东西啊,一个的话呢,是的是货取到所了嘛,应该是布尔类型的。啊,如果会锁成功,它就它这里面就是为就是为出啊。如果护理所失败,他认为false,并且的话呢,给我们拿到要监听的那个节点路径,它是个死定类型的,你要监听哪个节点,他把这节点路径呢,会给我们啊。好,我们直接啊再退回去。好,那么来看这个里面做什么处理,然后在这个该the lock里面,然后开始呢,去看一下我们这个序列化基点在整个秋瑞里面的这个下标啊,它的下标是多少。
26:10
那么会来下标之后呢,开始去验证了一下啊,验证这个这个这个下标。验证好下格之后呢,出现异常了,那出现异常之后呢,诶给我们执行这个删除操作,对啊删除操作出现异异常啊,进行删除操作,那正常情况下,我们这的话呢,是应该下标应该是几呢?应该是。应该是零,对啊,第一个元素下边不应该是零吗。但这里呢,验证失败了。验证失败了,把这个节点的给删掉了,删掉还会怎么样呢?哎,我们这个情况挺多的啊啊,又出现异常了,然于是又进行重试,反正就各种异常嘛,又进行重试去了啊。同时给过之后它会它会怎么样,我们来看一下啊,它是又得给我重建一个节点啊。嗯。好,我们这个它这个底层原理啊,其实搞得有点复杂哈。
27:04
啊,获利秋润应该是获益的,是那个为空了嘛,会到为空之后那个下标呢,就不正常了啊不正常之后呢,就给我们竞争。又可以进行重试一次,来走又被进行重试一次,又创建了一个这种节点。啊,创建成功了。创建成功之后呢,看判断一下有没有锁啊,我们再进去一次。啊,有锁这个有两个标识位啊,获取锁的标识位一个啥呢?一个是删除的一个标识位,有异常的情况下,它就会删除那个节点啊。OK,那么来走走走到这里面去。啊,那么首先呢,来去看,走走到下面来啊,它它会获取一个啊排行序的这个所有子节点,根节点下面的所有排行序的子节点啊,那我们来进行看一下。啊,然后进入一个重载方法,那这个方法呢,大家之前就看到过了,对吧。那获取这个所有的这个秋润啊,给你一下名字。基本节点,基本路径下面的所有的子节点。
28:02
那么会到这个时间点之后呢,开始进行,嗯,我们直接走走。开始进行排序对吧,然后排序,那排完序之后呢,哎,它这个排序啊,使用的是这个collection里面这个排序啊。排序,那么然后呢,并且重写了这个方法。那我们呢,就没有重写这个方法,那就使用那个默认排序,因为它默认呢,就是升序排列嘛,大单一直一呢走,嗯。走走,返回排好区域的这样的一个秋润啊,拿到这个排好区的秋润,那么排好序的秋润之后呢,那个秋润啊,所有的词里面有一个这一次获取到这个词啊。应该至少会有一个子对吧?啊,至少会有一个子,那么这个序列化节点,呃,在我们这个出人列表里面属于下标,是哪个下标呢?他要先获取这个序列化节点啊。啊,已经回到这个序列化节点了,看在这个出面列表里面的,呃,这个下标是几。下边是几?那么然后呢,呃,开始嗯,他去看看是不是当前这个地点是不是有损啊啊开始通过这个方来去判断,如果你的下表是零的话,是最小的那个下标的话,它就可以获取到锁了呀。
29:09
那否则的话就获取锁失败嘛,获取锁失败的情况下,他会给我们返回一个那个监听路径啊,监听的一个节点,然那个接点路径他就给我们啊好,这个对象咱已经看过了啊,前面已经看过了,那我们呢,再来去进入这两个方法看一下,首先呢,获取所有咱们获取这个当前这个节点序列化节点在所有子里面的这个下下标。拿这个下边之后呢,这个下边只能是零对吧,是零,然后验证一下,如果验咱这这一次验证没有问题,刚才咱验证出问题了啊啊被捕到异常了,所以呢,他又给我们把那个节点删掉,删了之后又重新创建了一次。啊,就很就很恶心啊,很麻烦啊,反复重试了好几次才回到一次锁。好,那么然后呢,我们再来去看看这个下标啊,咱们这个下标是不是小于最大阻约。卓越,那这项作业是一对啊是一,那我们这呢是一个零,那刚好小于家卓越。
30:04
如果你小于一的话,小于一的话,那只能是零了呀,那么是零的情况下,那说明你看就是第一个你就可以回到所,你看这个呢啊该the lock这个属性啊,它就会设置为出。就为处。然后呢,咱这个pass to watch,我还需要去获取这个,需要监听这个路径吗?不需要获取了。啊,如果我这个霍取锁失败了,霍取锁成功了,也不需要监听什么节点,它反了一个闹啊,不需要监听其他节点哈,如果我这里霍取锁失败的情况下,没有回到组的情况,我不是最小那个,那不是最小那个呢,它就会怎么样呢,它就获取。啊,比我们的下标小一的那个。来下边减上减,这不是一嘛,对吧,减一啊,减一比我们下边要小一的那个节点,那将来我们要监听这个下标小一的那个节点啊。二。那这个呢,就会给我们把这两个参数封装到这个predictate results里面去,好,那我们最终就拿到这样的一个结果了啊,那咱当前这个节点呢,能不能获取到所能已经获取到所成功了。
31:10
你看这个,就会判断这个值是不是为出,如果为出的话,那么这个has lock,呃,Has lock就为出。那么最终呢,它就会返回我们那个那个那个那个值哈,对吧,那个值。啊,此时这个do lock do体来的需要删除吗?不需要删除,然后返回这个has lock,这个has lock呢,就为true,或许所已经成功了。那会有所成功的情况下啊,那么此时呢,呃,我们开始去,嗯。开始去退出循环了,对吧,退出循环了,那最终呢,就嗯,返回一个我们当前这个节点的路径。当千基本路径。然后最终的话呢,就嗯。退出到我们这个lo里面去了。放log里面去了,然后呢,这个呃,Log pass如果不为空啊,开始去给我们进行制作重录信息啊。
32:03
啊,创建一个重入信息当前这个线程,然后呢,嗯,这个路径的所的啊,然后呢,重入了是一次要的啊,它有一个lock data这个重入信息。那么重复信息呢,是哪个线程线程啊对象给放进去,那么然后呢,是哪个锁对吧?它那个节点的全路定啊会给我们放进去,然后默认值呢是只能是一,那此时呢,获了获取了一次锁,我们这个线程。啊就这样的啊,然后呢啊,再把这个呃,Lock data这个对象啊,Lock data这个对象啊,然后放到这个看哈map里面去啊,这个东西咱一开始呢,就就介绍过这这几行代码啊,然后放进之后呢,就开始成一个出获取所已经成功了啊重入了一次对吧,那我们紧接着再去找。好,那我们第二次开始去获取锁。那么第二次获取锁的时候呀,他怎么走呢?直接F7进去啊。啊,然后呢,在F7进去,进去之后呢,获取当天线程,要从当天线程啊,通过当天线程那就获取哈map里面这个lock data lock data呢为空吗?不为空,因为当前线程已经获取过一次扫法,那不为空的情况下,他开始对我们这个lock count啊进行了进行递增操作。
33:15
啊进行操作,然后呢,呃,重入成功。而还需要在充点节点什么之类的吗?就不需要了啊,那此时呢,就直接返回成功就可以了。啊,直接返回成功就可以了,货到手了,大概进行业务操作。好,那么咱们这个加锁以及重入这一块呢,我们就全部看完了啊,那最终结果的话呢,咱就这样子的啊。那么很多大部分操作都在这个temp lock里面来操作的。那这里面呢,它就会给我们创建咱们那个序列化节点,咱们继续看一下这个lock里面这个方法啊。咱们这周的话呢,是这个是interlock interlock里面是调用了我们这个temp,呃,Temp,呃,Lock。那这里面就给我们创建一个序列化节点,那当然呢,它里面呢,给我们做了一些路径处理什么之类的啊。
34:05
然后呢,创建好这个序列化节点之后呀,开始去判断我们这个节点呢,哎,是不是最小那个。如果是最小那个,那咱也可以获取所成功,如果不是最小那个,它会怎么样呢?啊,在这个inter lo loop里面啊,Loop里面他就跟他去监听那个,监听那个比他小的节点哈。因为这个呢,是那个获取锁那个方法返回一个断言对象吗?断言结果对象啊,那么这个断言结果对象里面如果是为处该lock为触的话。那么说明咱就可以获取锁成功直接返回就可以了,咱刚才直接返回的啊,获取锁成功直接返回,那如果咱没有获取到成功呢,我当前基点不是最小那个,他这样的话就会给我们添添加监听时间。哎,在这个里面添加监听时间的啊啊,他这呢有这个他通过这个get data查询查询数据,查询节点数据,然后呢,添加监听的。
35:00
他凭哪个路径添加监听,给前面那个序列化节点添加监听,给前一个序列节点添加监听啊。啊,那么然后呢,我们这个呢,它使用的话,使用的是该啊get get这样的一个方法,而不是使用的是exist这个方法,它为了避免什么呢?为了避免啊,不必要的监听啊防止啥呢?防止呃这个资源泄露,他这么一说的。因为你类似啊,他好像成功不成功,他都会去提前听啊,就这个节点是否存在,他都会提前提前监听。啊,比如前个节点的如果不存在了,它也会添加静听啊get that的话呢,是get that是不会的啊。啊,它就可以防产呢,防止资源浪费,那我们今天使用就是这个东西,所以呢,咱写的那个呀,也是有可优化空间的啊好,那么咱们这个枷锁呢,我们就看到这里了,那总体来看呢,它的枷锁呀,看上去业务呢非常非常的复杂,那么然后一个方法调着一个方法,然后路径的话呢,又绕过来绕过去的,但最终的这个实现理念啊是一样的啊。
36:03
啊,都怎么回事呢?都创建一个临时序列化节点,那么然后再去判断当前这个节点呢,是不是最小的一个。啊,然后如果不是最小那个,我们来监听前一个节点啊,如果是最小的,我们就可以获取所成功。好,那么基本理理论都差不多啊,那你跟面试官聊的时候呢,你可以结合我们那个实现啊来去说哈呢,说他的这个实现就可以了,那我带你们去实现一遍了,那你能不能去说一说呢?哎,当然可以说了,你就按照我们那个实现过程的一说就可以了,那没有必要呢,非得要跟他啊,跟他这个一模一样啊。OK,那么这是咱们这个枷锁,我们来去看这个解锁吧啊。那么解锁这个东西呢,怎么解呢?啊,我们再次去往下看啊,首先呢,咱是第一次解锁,我们直接呢走这是第一次解锁。那么然后呢,这是第二次解锁啊,第一次解锁它应该是出来一次,OK,那我们来去进去看一下,那么此时呢,这个解锁呀,它还是去获取当天线程。
37:05
然后从咱们这个他敞开的哈希map里面,通过线程对象获取这个所咱这个重熟信息。那如果是重复信息为空,就抛出异常,抛出错误的监听状态异常。他说呢,你这个没有这个锁,你怎么能去啊解锁呢,对吧?啊OK,那么如果他嗯不为空,那他开始干嘛呢?开始去减一啊减一操作,那么减完一之后呢,如果大于零,那减完一之后就可以了呀,就可以直接停了呀,那如果小于零呢。啊,小于零的话也会有,也会报异常,你不可能小于零的。只有什么情况,只有等于零的时候,我们才需要去release,把那个节点的格式放掉啊?好,那我们来去看一下这个地方,咱已经啊减减减完一之后依然大于零,因为它现在重入了两次啊啊重入了一次,最后结果是二对吧,减完一一次之后呢,还等于一呢,等于一一不是大于零吗。那次到这个一呢,是大于零的,大于零之后呢,我们不能去把那个节点给删除,于是直接平就可以了。
38:07
那在格之后呢,来看它第二次解锁会怎么样呢?你这第二次解锁,那么第二次解锁,那么咱们这个还是一样,先获取这个锁定信息啊,重复信息,那么它重复信息啊,还是进行减一,减完一之后呢,此时大于零吗?哎,不大于零了,它等于零。那么小于吗?如果小于零,抛出异常,那么也不小于零,那不大于零,也不小于零,那么就等于零了吗?那开始就执行这样的一个Internet里面的release lock方法。那我们直接去进去看一下啊,F7进去。好,那么在这个里面呢,先去去除监听啊,去除监听,把监听给去掉。那么然后呢,我们再去走啊,反正把某个东西呢,设置为空,设置为空之后呢,开始去删除啊,咱们这个锁路径对应的节点哈,那叫索路径的话呢,就是咱们这个这样的一个路径啊,对应的节点把它给删掉好我们直接走。
39:02
好,F7进去啊,建议这个就没啥可看的了啊,这个通过客户端,然后去删除,删除咱们这个路径定向节点好。啊,那么咱就直接啊F9放行就可以了。啊,所以的话呢,它这个锁的实现啊,总体来说呢,其实嗯,都是差不多的啊,跟我们都是差不多。
我来说两句