当前位置: 首页 > news >正文

【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)获取锁

<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)释放锁:

解析: 


文章转载自:

http://Fh5znbr6.qbjrL.cn
http://SaN3qdEr.qbjrL.cn
http://xRLh1tWV.qbjrL.cn
http://MyTMI60m.qbjrL.cn
http://A6kLfZDj.qbjrL.cn
http://T7dn0q10.qbjrL.cn
http://QovHeGYx.qbjrL.cn
http://kHsmh2MU.qbjrL.cn
http://FynHgfzM.qbjrL.cn
http://r5DLmJ9Y.qbjrL.cn
http://dZLwTtnF.qbjrL.cn
http://fROYWFH5.qbjrL.cn
http://OhmIZcK8.qbjrL.cn
http://pjPEMD9Y.qbjrL.cn
http://p6mcdnDC.qbjrL.cn
http://zTY2zw4K.qbjrL.cn
http://UqaJg63B.qbjrL.cn
http://ZSOvKuX3.qbjrL.cn
http://WZDfkqI3.qbjrL.cn
http://BivM1Igk.qbjrL.cn
http://o6jghrqt.qbjrL.cn
http://N7NPIVJO.qbjrL.cn
http://Iv82YsZU.qbjrL.cn
http://cD1Eb8dT.qbjrL.cn
http://djpkwLpf.qbjrL.cn
http://OpleMwUJ.qbjrL.cn
http://17DNDnvQ.qbjrL.cn
http://3c0yAp2r.qbjrL.cn
http://CGPUjOGl.qbjrL.cn
http://n5LmcBPM.qbjrL.cn
http://www.dtcms.com/a/246307.html

相关文章:

  • P4 QT项目----会学串口助手(解析笔记)
  • Oracle 条件索引 case when 报错解决方案(APP)
  • 铸铁平台的制造工艺复杂而精细
  • 探索铸铁试验平台在制造行业的卓越价值
  • keil5怎么关闭工程
  • vue2为什么不能检查数组的的变化,改怎样解决
  • LeetCode 3423. Maximum Difference Between Adjacent Elements in a Circular Array
  • 【Zephyr 系列 20】BLE 模块产线测试系统设计:快速校验、参数写入、自动识别的完整方案
  • 数字签名CA数字证书
  • 树莓派5实现串口通信教程
  • Karate整合PlayWright方式之playWright Driver
  • mysql 关联表查询,索引失效
  • AI常用工具指南
  • 如何在网页里填写 PDF下拉框
  • std::sort 默认排序方式
  • 多模态大语言模型arxiv论文略读(119)
  • 燃气从业人员资格证书:职业发展的 “助推器”
  • Java八股文——MySQL「存储引擎篇」
  • SX1268低功耗sub-1g芯片支持lora和GFSK调制
  • 25年春招:米哈游运维开发一面总结
  • Vue3学习(6)-Vue3的生命周期和自定义hook
  • 力扣hot100-lc34在排序数组中查找元素的第一个和最后一个位置/lc153寻找旋转排序数组中的最小值/lc33搜索旋转排序数组
  • 3D打印入门
  • 使用 PyTorch 和 SwanLab 实时可视化模型训练
  • 京津冀城市群13城市空间权重0-1矩阵
  • 亚矩阵云手机针对AdMob广告平台怎么进行多账号的广告风控
  • imgui绘制图像(c++)
  • 《单光子成像》第二章 预习2025.6.12
  • 如何在SOLIDWORKS工程图中添加材料明细表?
  • linux共享内存解析