redis面试(十六)公平锁释放和排队加锁

18 篇文章 0 订阅

锁释放

RedissonFairLock.unlockInnerAsync()方法
这和加锁的逻辑没有太大区别
在这里插入图片描述
也就是说在客户端A他释放锁的时候,也会走while true的脚本逻辑,看一下有序集合中的元素的timeout时间如果小于了当前时间,就认为他的那个排队就过期了,就删除他,让他后面重新尝试获取锁的时候重排序

while true的逻辑,比如说客户端B或者客户端C,他们用的是tryAcquire()方法,他们其实设置了一个获取锁超时的时间,比如说他们在队列里排队,但是尝试获取锁超过了20秒,人家就不再尝试获取锁了

此时他们还是在队列和有序集合里占了一个坑位,while true的逻辑就可以保证说剔除掉这种不再尝试获取锁的客户端,有序集合里的timeout分数就不会刷新了,随着时间的推移,肯定就会剔除掉他

如果客户端宕机了,也会导致他就不会重新尝试来获取锁,也就不会刷新有序集合中的timeout分数,不会延长timeout分数,while true的逻辑也可以剔除掉这种宕机的客户端在队列里的占用

因为网络延迟等各种因素在里面,可能会在等待锁时间过长的时候,触发各个客户端的排队的顺序的重排序,有的客户端如果在队列里等待时间过长了,那么其实是可以触发一次队列的重排序的

他在这里发布一个锁被释放的消息,肯定在他的源码中是有一些人是订阅了这个释放锁的消息的,此时他们就可以得到一个锁被释放掉的通知

排队加锁

如果客户端A释放了锁,删除了锁key之后,客户端B和客户端C是如何按照顺序依次加锁的。
要记得,刚才我们经历了队列重拍,排在队头的是客户端C,后面是客户端B
假设锁被释放掉了之后,如果客户端B先来尝试加锁

客户端B加锁失败

10:00:40,锁已经被释放了,客户端B来尝试重新加锁

10:01:04 <= 10:00:40?不成立

exists anyLock = 0,当前锁不存在;exists redisson_lock_queue:{anyLock} = 0,要不然就是队列不存在,但是现在队列是存在的;lindex redisson_lock_queue:{anyLock} 0 = UUID_02:threadId_02,队列存在,但是排在队列头部的不是客户端B的线程

所以上面整体条件不成立,无法加锁

ttl = 10:01:04 - 10:00:40 = 24000毫秒
timeout = 24000 + 10:00:40 + 5000 = 10:01:09

zadd指令,刷新一下客户端B在有序集合中的timeout分数,10:01:09

哪怕是锁释放掉了,其他各个客户端来尝试重新加锁也是不行的,因为此时排在队头的不是这个客户端也不行,此时只会重新计算timeout分数刷新一下有序集合中的timeout分数罢了

客户端C加锁成功

此时客户端C来尝试加锁会如何?

anyLock锁key不存在的;队列是存在的;队列的队头就是客户端C,所以此时加锁的条件成立了,进入加锁的逻辑

lpop redisson_lock_queue:{anyLock},将队列中的第一个元素弹出来
zrem redisson_lock_timeout:{anyLock} UUID_03:threadId_03,将有序集合中的客户端C的线程id的元素给删除掉
hset anyLock UUID_03:threadId_03 1,加锁
pexpire anyLock 30000,设置生存时间为30000毫秒

完成加锁,而且客户端C从队列中出队,此时排在队头的就是客户端B了

获取锁超时,其他客户端获取不到锁,一定会在java代码里进入一个while true死循环,一定时间内没有获取到锁,就返回false标识获取锁失败,过了一段时间,只要没有刷新有序集合中的timeout分数,就会自然被lua脚本里的while true逻辑给清理掉

超时自动释放锁,不会开启lock watchdog后台定时调度的任务

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木小同

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值