【Redisson】四.可重入锁-可重入加锁源码
前言
主要介绍Redisson可重入锁,实现可可重入加锁的源码解析
源码分析
这里回头看看加锁的代码如下
<T> RFuture<T> tryLockInnerAsync(long leaseTime, TimeUnit unit, long threadId, RedisStrictCommand<T> command) { internalLockLeaseTime = unit.toMillis(leaseTime); return evalWriteAsync(getName(), LongCodec.INSTANCE, command, "if (redis.call('exists', KEYS[1]) == 0) then " + "redis.call('hincrby', KEYS[1], ARGV[2], 1); " + "redis.call('pexpire', KEYS[1], ARGV[1]); " + "return nil; " + "end; " + "if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " + "redis.call('hincrby', KEYS[1], ARGV[2], 1); " + "redis.call('pexpire', KEYS[1], ARGV[1]); " + "return nil; " + "end; " + "return redis.call('pttl', KEYS[1]);", Collections.singletonList(getName()), internalLockLeaseTime, getLockName(threadId)); }
其中lua脚本中的第二个分支
//如果当前线程已经获取到锁 "if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " //将锁表示的对象的值,进行 加1 "redis.call('hincrby', KEYS[1], ARGV[2], 1); " + //设置锁的过期时间为 internalLockLeaseTime leaseTime(默认为30000毫秒)
"redis.call('pexpire', KEYS[1], ARGV[1]); " + "return nil; " +
这里回过头看redisson加锁实现的hash数据结构
此时的value的值1, 就是和锁的可重入有关,表示持有锁的线程对当前锁的重入次数
测试demo
这里执行一段代码测试下Reddsson可重入锁。同时观察下Redis中value值的变化
@ApiOperation(value="redis可重入锁测试") @GetMapping(value = "/reentrantTest") public BaseOutput<?> redisDemo(){ log.info("当前线程Id:{}",Thread.currentThread().getId()); RLock lock = redissonClient.getLock("lock"); log.info("第1次加锁"); lock.lock(); log.info("第2次加锁"); lock.lock(); log.info("第1次释放锁"); lock.unlock(); log.info("第2次释放锁"); lock.unlock(); return BaseOutput.success(); }
1.第一次加锁redis value值为1
2.第二次加锁redis value值为2
3.第一次释放锁,value值减一,value为1
4.第二次释放锁,value值减一,锁完全释放,redis key被删除
分类:
Redis
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2020-02-06 【接口设计】高并发下的接口幂等性的实现