【Redisson】锁可重入原理

目录

一、基本原理

二、源码解析:

(2)获取锁

(1)释放锁:


之前给大家介绍过redisson的分布式锁,用redisson来实现比自己手搓简单的分布式锁有很多好处,因为这些可重入、可重试的逻辑较为复杂,他们的lua脚本不可能让我们在开发时自己实现,这样太耗时间了。所以redisson就帮我们实现了可重入和可重试。但我们也要知道他的原理,这期我们先讲可重入。


上一篇:

【Redisson】快速实现分布式锁-CSDN博客


一、基本原理

基本原理:

(1)获取锁的时候,还是使用setnx命令,如果该锁还没有被获取过,直接set,也就是获取锁成功

(2)当该线程第二次获取锁时,因为锁已经被获取了,也就是setnx返回false。这时候,先不直接返回获取锁失败的逻辑,而是先判断该锁的value值是不是自己,如果是,那么就获取锁成功。

(3)有一个计数器,每次获取锁成功计数器就+1,每次释放锁的时候计数器就-1。当计数器为0的时候表明该线程所有重入的锁都被释放完毕了,就可以删除这个key。那么其他线程就可以获取锁了

(4)因为key的value值既要记录线程标识,也要记录重入次数。所以String类型的结构就不满足了。需要使用到hash结构

(5)注意:每次释放锁时,如果value值不是0,说明该锁还是被该线程占用的。也就是释放重入锁的时候,要重置锁的有效期

图解:



二、源码解析:

(2)获取锁

java 复制代码
<T> RFuture<T> tryLockInnerAsync(long waitTime, long leaseTime, TimeUnit unit, long threadId, RedisStrictCommand<T> command) {
            return this.commandExecutor.syncedEvalNoRetry(this.getRawName(), LongCodec.INSTANCE, command, 
                    "local mode = redis.call('hget', KEYS[1], 'mode');" +
                    "   if (mode == false) then " +
                    "       redis.call('hset', KEYS[1], 'mode', 'read');" +
                    "       redis.call('hset', KEYS[1], ARGV[2], 1);" +
                    "       redis.call('set', KEYS[2] .. ':1', 1);" +
                    "        redis.call('pexpire', KEYS[2] .. ':1', ARGV[1]);" +
                    "       redis.call('pexpire', KEYS[1], ARGV[1]);" +
                    "       return nil;" +
                    "   end;" +
                    "   if (mode == 'read') or (mode == 'write' and redis.call('hexists', KEYS[1], ARGV[3]) == 1) then" +
                    "        local ind = redis.call('hincrby', KEYS[1], ARGV[2], 1);" +
                    "        local key = KEYS[2] .. ':' .. ind;redis.call('set', key, 1);" +
                    "        redis.call('pexpire', key, ARGV[1]);" +
                    "        local remainTime = redis.call('pttl', KEYS[1]);" +
                    "        redis.call('pexpire', KEYS[1], math.max(remainTime, ARGV[1]));" +
                    "        return nil;" +
                    "   end;" + 
                    "return redis.call('pttl', KEYS[1]);",
                    Arrays.asList(this.getRawName(), this.getReadWriteTimeoutNamePrefix(threadId)), new Object[]{unit.toMillis(leaseTime), this.getLockName(threadId), this.getWriteLockName(threadId)});
        }

解析:

(1)释放锁:

解析:

相关推荐
江屿风3 小时前
【Plain Language Large Model】【从麦当劳点餐到Redis接入:MCP如何让AI工具集成变简单】流食般投喂
人工智能·redis·笔记·语言模型·llm·mcp
骑着蜗牛撵大象3274 小时前
558 万美元训出 671B 模型:DeepSeek-V3 算法与系统的协同拆解
分布式·算法·moe·deepseek-v3·mla·fp8训练
德迅云安全-上官4 小时前
德迅游戏盾:面向 TCP 业务的分布式云安全防护方案
分布式·tcp/ip·游戏
码智社5 小时前
Redis 哨兵模式详解:从原理到生产实践
java·redis
麻瓜code6 小时前
分布式锁演进:从一个用户下两单,到 Redisson,我改了四版
分布式·wpf
与数据交流的路上7 小时前
一次 redis 幽灵内存的分析
数据库·redis·缓存
skywalk81637 小时前
hive —— 多机 AI Agent 协同的任务总线:分布式,多节点同时运行,保障不会宕机
人工智能·hive·分布式
一条泥憨鱼7 小时前
【RabbitMQ】高级篇
java·分布式·rabbitmq·php·ruby
棣廷9 小时前
初识Spark Core
大数据·分布式·spark
凯凯姜17 小时前
分布式锁场景问题
分布式