可以看到,其实又是一段lua脚本,继续复制出来分析一下 。
-- KEYS[1] 加锁的对象(也就是我们传入的的锁名称)-- KEYS[2] 监听该锁的频道 也就是publish要发送锁被释放的频道,用于在锁释放时通知其他客户端可以重新获取锁了-- ARGV[1]:解锁消息-- ARGV[2] 表示锁的过期时间-- ARGV[3]:UUID+当前线程id-- 先判断自己的锁是不是已经释放了 ==0 表示key不存在了,也就是锁被释放了if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then-- 返回nil,也就是null, 表示释放锁成功return nil;end ;-- 对锁的重入次数减一因为重入一次counter会+1,所以释放时每次也只能-1,跟重入次数匹配local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1);-- 如果重入次数仍然大于0,续约过期时间if (counter > 0) thenredis.call('pexpire', KEYS[1], ARGV[2]);-- 返回解说失败return 0;else-- 表示重入次数已经为0了,删除锁的keyredis.call('del', KEYS[1]);-- 使用publish发布一个消息,其他订阅了的客户端收到消息,就说明解锁成功了饿、然后可以重新获取锁了redis.call('publish', KEYS[2], ARGV[1]);-- 返回1 表示解锁成功return 1;end ;return nil;其实就是在解锁的时候,已经解锁了直接返回成功,可重入次数没有到0,将会解锁失败,直到可重入次数重新减到0后,开始删除锁的key.
并且此时会使用publish发送一个消息在渠道上,订阅者们订阅到了,就说明锁已经被释放了,然后可以从重新获取锁了 。
3、小结Redisson实现分布式锁,就是使用lua脚本保证原子性和互斥性的 。每次都判断是不是自己持有锁,才进行操作,这就保证了同一性 。
在加锁时使用incrby对key对应的value值进行自增,减锁时自减实现锁的可重入性 。
使用redis的超时自动过期来保证锁的容错性,不会一直锁死下去 。所以锁的最大续约时间是防止思索的一个有效的方法 。
推荐阅读
- 一文吃透JVM分代回收机制
- Springboot+Redisson封装分布式锁Starter
- AMD中国特供新卡RX 6750 GRE:原来是RX 6700矿卡解锁
- 解析SPI机制:实现灵活插件式架构
- 苹果激活锁是啥意思 苹果激活锁是什么意思
- 设置苹果面部解锁步骤方法 苹果咋设置面部解锁
- 起猛了!赵丽颖谢娜一起看张杰演唱会,还现场解锁了新技能蹦迪
- 《四方馆》首发剧照,檀健次解锁新造型,女主表现超预期!
- 七夕,翡你不可,用翡翠锁住心上人
- 立竿见影!教师“退出机制”才刚落地,教师招聘就“遇冷”了?
