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

redis面试(十四)公平锁可重入

可重入

就是当前线程多次加锁
while true,lindex redisson_lock_queue:{anyLock} 0,获取队列第一个元素,判断一下他的timeout时间是否大于当前时间了,假设当前时间是10:00:08,此时肯定是是不成立的,假设就直接跳出死循环

当前锁是否不存在,不成立;hexists anyLock UUID_01:threadId_01,在anyLock hash中,是否存在一个UUID_01:threadId_02的key,当前这个锁是否是客户端A加锁,成立,hincrby给加锁次数累加1,重新pexpire刷新锁key的生存时间为30000毫秒,返回一个nil

此时可重入加锁成功,无非就是累加了1次加锁的次数

分数刷新

在排队中的客户端,模拟等待一段时间后,再次尝试加锁。

第二个线程第二次尝试加锁

客户端B,10:00:00,10:00:15,他来再次尝试进行加锁,但是客户端A此时还是持有着这把锁的,此时会出现什么情况呢?

while true,获取队列第一个元素,同时获取这个元素的timeout时间,10:00:25 <= 10:00:15?不成立,while死循环退出

判断一下是否没人加锁,以及判断是否是客户端B进行的加锁,都不成立

ttl = 10:00:25 - 10:00:15 = 10000毫秒
timeout =10000毫秒 + 10:00:15 + 5000毫秒 = 10:00:30

zadd redisson_lock_timeout:{anyLock} 10:00:30 UUID_02:threadId_02,刷新一下有序集合中的元素的分数,10:00:30

大致可以理解为,你的某个客户端不是在不断的重试尝试加锁么?每次重试尝试加锁的时候,就判定为是这个客户端一次新的尝试加锁的行为,此时会将这个客户端对应的timeout时间往后延长,10:00:25,这次他重试加锁之后,timeout时间算出来就变成10:00:30,把这个客户端的timeout时间延长了,有序集合中的分数变大了

if redis.call(‘zadd’, KEYS[3], timeout, ARGV[2]) == 1 then

zadd指令的返回值,如果是第一次往里面怼入一个元素,返回值是什么?如果是第二次刷新这个元素的分数,返回值是什么?如果是第一次插入一个元素在有序集合中,此时就会返回值是1,同时会入队;但是后续不断的尝试加锁的时候,其实是会不断的刷新这个有序集合中的元素的分数,越来越大,但是每次刷新分数,返回值是0

所以不会重复的往队列中插入这个元素的

第三个线程第二次尝试加锁

客户端C,10:00:20,再次尝试加锁

10:00:30 < 10:00:20?不成立;尝试加锁,都不成立

再次刷新他的timeout分数

ttl = 10:00:30 - 10:00:20 = 10000毫秒
timeout = 10000毫秒 + 10:00:20 + 5000毫秒 = 10:00:35

zadd redisson_lock_timeout:{anyLock} 10:00:35 UUID_03:threadId_03

还是维持着跟之前一样的这么一个顺序,客户端B的分数会刷大,客户端C的分数其实也在不断的刷大,所以在有序集合中的分数的大小的顺序,基本上还是按照的是最初他们是如何排队的,此时也会如何排队

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【Linux入门】root密码忘记了怎么办?
  • 乳制品企业怎么防止信息泄露?使用加密软件保障数据安全
  • laravel 11 使用jw-auth进行API 登录
  • vs2022 启动之后崩溃解决方案
  • 学习嵌入式入门(十)高级定时器简介及实验(下)
  • 关于MariaDB
  • 测试需求分析(四)
  • winform中设置DateTimePicker参数为空
  • 【C++】什么是模板?
  • 第二证券:虚拟现实概念强势,博士眼镜三连板,星星科技涨停
  • spring mvc工作流程
  • 小试牛刀-区块链Solana多签账户
  • 血缘系统 datahub + Sqllineage
  • 修改docker的/var/lib/docker/overlay2储存路径
  • mac 链接数据库报错 - Public Key Retrieval is not allowed
  • Angular 响应式表单之下拉框
  • const let
  • ECS应用管理最佳实践
  • ES6核心特性
  • Java 23种设计模式 之单例模式 7种实现方式
  • java2019面试题北京
  • Java到底能干嘛?
  • js ES6 求数组的交集,并集,还有差集
  • Laravel核心解读--Facades
  • Node.js 新计划:使用 V8 snapshot 将启动速度提升 8 倍
  • PHP面试之三:MySQL数据库
  • Rancher如何对接Ceph-RBD块存储
  • react 代码优化(一) ——事件处理
  • vue-cli3搭建项目
  • 安卓应用性能调试和优化经验分享
  • 闭包--闭包之tab栏切换(四)
  • 得到一个数组中任意X个元素的所有组合 即C(n,m)
  • 关于Flux,Vuex,Redux的思考
  • 关于使用markdown的方法(引自CSDN教程)
  • 事件委托的小应用
  • -- 数据结构 顺序表 --Java
  • 我建了一个叫Hello World的项目
  • 学习笔记TF060:图像语音结合,看图说话
  • const的用法,特别是用在函数前面与后面的区别
  • linux 淘宝开源监控工具tsar
  • 专访Pony.ai 楼天城:自动驾驶已经走过了“从0到1”,“规模”是行业的分水岭| 自动驾驶这十年 ...
  • ​如何使用ArcGIS Pro制作渐变河流效果
  • #if 1...#endif
  • (1)svelte 教程:hello world
  • (HAL)STM32F103C6T8——软件模拟I2C驱动0.96寸OLED屏幕
  • (附源码)springboot学生选课系统 毕业设计 612555
  • (附源码)ssm高校社团管理系统 毕业设计 234162
  • (附源码)ssm捐赠救助系统 毕业设计 060945
  • (规划)24届春招和25届暑假实习路线准备规划
  • (顺序)容器的好伴侣 --- 容器适配器
  • (详细版)Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models
  • (译) 函数式 JS #1:简介
  • (原創) 物件導向與老子思想 (OO)
  • (转)大型网站的系统架构
  • (转)全文检索技术学习(三)——Lucene支持中文分词