00:00
下面呢,我们来对咱的分布式所做一个小结,那我们手写分布式所,咱一共实际上六个特征,首先呢,最基本的是独占排它,那咱通过set X指令就可以做到独占排他了。那么然后呢,我们还做到防死锁,那么3X啊,咱要去设置过期时间来去防死锁。那么如果我们使用塞塔X的话,就要结合XPI来设置过去时间,那么两个指令之间咱很难保证原子型啊,那么于是呢,我们就开始使用set啊,Key啊,Value,然后呢,通过EXX设置过期时间,最后来一个NEX就可以了。那么这样的话呢,既可以保证独占排他,又可以防止客户端程序宕机带的搜索问题。但是我们依然会有一个搜索问题呢,就是不可重入也可能会导致搜索,那于是呢,我们后续啊,又实现了可重入锁哈。
01:00
那么来看这个防护衫,那防护衫呢,我们要先判断是不是自己的锁,如果是自己的锁我们才能去删除,否则呢,咱不能去释放这个锁。啊,所以呢,解铃还需系铃人。那么第四个呢是原子性。那么原子性呢?咱有两个地方要保证原子性,那么加速和过期时间之间要保证原子性。那么我们判断和释放所之间也要保证原子性。那么这一块的话呢,加锁和过期时间啊,咱是通过TV就很容易实现了啊,那么set t VE ex以及呢,NX就可以实现了。那判断和释放所之间怎么保证原子性呢?咱们使用的是路啊,脚本,它就保证的。那么咱最后呢,又实现了可重入锁自动续期,那么可重入锁呢,咱去注意哈希数据模型。那么这个哈希数据模型。
02:00
我们会以所的名称作为K啊,咱们会有K会有field的,以UUID啊,以UUID啊,最终的话呢,咱是UID加线程ID啊,那作为CU得到。那最后呢,是我们的重入次数。重复次数作为value啊,给它放到一个哈希数据模型里面的。啊,那么然后是化脚本可以保证原子性。那么还有呢,最后呢是自动续期,咱通过time定时器结合R脚本来去实现了自动续期。好,那么最后呢,我们来从锁操作这个角度来去总结一下啊,这个维度呢,我们主要是分成三个操作,那么一个呢是加锁还有解锁以及重试。啊加锁呢,又分成了四个版本。首先呢,是第一个版本,它始终是set n,那么使用它呢,可以基本去实现我们的独占排他这样的一个效果,但是呢,它可能会引发搜索。
03:00
比如说呢,客户端程序,嗯,客户端程序release,客户端程序获取到锁之后呢,服务器立马宕机了,能带来的搜索以及不可重入也可能会引发搜索。那么然后原子性也很难去保证,比如说呢,我要给这个锁呀,设置过期时间,那么设置过期时间以防止锁锁呀,但是呢,原子性很难去保证。那于是呢,咱使用第二个版本,我们就使用CKV,然后exx设置过去时间,然后exx呢,保证独占排他。那么它呢,就可以防止客户端程序宕机带来的思索问题啊,同时做到独占排他,但是呢,它还是不具备可重入性。那么最后的话呢,我们要使用哈希加辣脚本,那也是咱第三个版本了,来去实现可重入锁。那么这个实现思路啊,在这个地方一共这三个步骤,这三个步骤呢,要记下来。那你跟面试官聊的时候,你怎么实现第三个版本的?
04:02
好,那么你跟面试官聊的时候呀,你也可以说呢,咱最开始使用SX啊,然后SX出现了什么问题,那于是呢,我们就使用SPVE这样的一个玩意。那么使用它呢,又可能是不可重入带来思索,于是呢,我们又实现了是可重入索,这个那可重入锁,你的实现思路什么样子的?那主要是撸脚本里面的那三句话,首先我们得要去判断咱的所设备占用。那如果没有被占用,那我们就上去就可以获取锁了,哎,通过h set或者是h increase by,那就可以获取锁了哈。那并且咱们就通过XPL设置过期时间啊,防止客户端程序宕机带来的思索问题。如果有人占用锁了,或者锁被占用了,那怎么办呢?我们需要判断是不是当前线程占用了锁。那如果是当前线程占用的锁,我们进行重入呀。
05:00
好,那么怎么判断是否半截线占用的锁呢?我们可以通过H这个Z这个指令啊,XZ这个指令。好,那么然后呢,判断完之后啊,判断完之后呢,如果是自己的,如果等于一,这个时间反应就等于一。这说明是自己的,那则你可以进行重铸,通过he increase by来递增一就行了。并且呢,我们要重置过期时间,通过PI来设置过期时间。好,那么如果以上条件都不满足,则获取所失败,那咱将来呢,可以呢,进行重试就行了啊。他是咱第三个版本的。枷锁啊,那这一块的话呢,呃,你跟面试官聊的时候呀,就可把这样的三句话呢,跟面试官去聊一聊了啊怎么实现的分析一下。啊,那么然后呢,第四个版本。第四个单位呢,我们实现了自动自动续期,通过time定时器结合卢瓦脚本来实现了所得自动续期。
06:03
那么他们定时器呢,没什么可说的啊,这是JDJDK给咱提供的Java u,求提供的一个工具啊工具类。那么其实说白了,它也是一个子线程来实现的。啊,那么这个路R脚本,R脚本呢,它也有思路,在我们续期的时候,咱不能随便去续期啊,我们第二去判断。是否或者说自己的所是否存在,或者呢,是判断当前这个所是否自己的啊。判断所是否自己的锁,那怎么判断是否自己的锁呢?那通过HXZ这个指令来判断的。如果等于一,说明就是自己的数。那么如果是自己的所则则咱就要去执行执行XP这个指令来去重置过期时间就可以了。
07:03
好,那么这是咱们这个枷锁的时候,这是四个版本哈。那最终我们的实验是三四这两个单位结合在一起了。好,那么然后呢,解锁呀,我们对应的是前三个枷锁啊。因为过期时间这一块呢,咱解锁的时候没做什么操作。好,首先呢,咱如果使用是set类加锁的,那对应的咱使用的是Del指令来去。解锁的啊,那这种解锁可能会导致误删。那咋咋解决呢?我们要先判断再删除,同时策略要保证原则性。那么怎么做到先判断再删除,还能保证原子性呢?那肯定要去使用脚本。那么然可从动索,我们也通过第三个版本可从动索,但也通过卢瓦脚本来实现的,那么哈希结合鲁瓦脚本。那对应的是第三个版本的枷锁啊。好,那我们来看啊,首先呢,我们需要判断当前线程的锁是否存在,如果不存在,说明是恶意释放锁,那就直接返回NL。
08:10
将来在程序里面抛出异常就可以了。好,那么第二个版本啊,第二步。啊,如果存在自己的所存在,那么咱就直接进行减一,1Q8负一就可以减一了。然后再去判断减一后的值是否为零,为零说明它减完了,我们就可以通过第二指令等于释放所了。并且返回一个一代表呢释放所成功。好,那么如果没有减为零。哎,咱就啥都不用干了呀,剪完之后就可以了,就啥都不用干。那么咱就直接返回一个零代表呢,我出来了一次。好,那么重试呀,咱可以通过递归来进行重试,那么也可以通过循环来重试,这两种方式呀,我们都演示了啊。好,那么来小节呢,就到这里。
我来说两句