NO.1

前言

NO.2

原理分析

while true do
local firstThreadId2 = redis.call('lindex', KEYS[2], 0);
if firstThreadId2 == false then
break;
end;
local timeout = tonumber(redis.call('zscore', KEYS[3], firstThreadId2));
if timeout <= tonumber(ARGV[4]) then
redis.call('zrem', KEYS[3], firstThreadId2);
redis.call('lpop', KEYS[2]);
else
break;
end;
end;
if (redis.call('exists', KEYS[1]) == 0) then
local nextThreadId = redis.call('lindex', KEYS[2], 0);
if nextThreadId ~= false then
redis.call('publish', KEYS[4] .. ':' .. nextThreadId, ARGV[1]);
end;
return 1;
end;
if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then
return nil;
end;
local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1);
if (counter > 0) then
redis.call('pexpire', KEYS[1], ARGV[2]);
return 0;
end;
redis.call('del', KEYS[1]);
local nextThreadId = redis.call('lindex', KEYS[2], 0);
if nextThreadId ~= false then
redis.call('publish', KEYS[4] .. ':' .. nextThreadId, ARGV[1]);
end;
return 1;
复制
熟悉的代码,上来就是进入循环判断头结点是否超时,是否需要进行清理,果然还是会有清理操作
为什么呢?我们在客户端加锁的时候,会进行一波清理,清除掉过期的,找到第一个不过期的节点,但是,如果这个节点之后有一部分过期了呢?怎么办?所以释放锁的时候就会进行清理操作
判断锁是否还存在,不存在则直接返回,并发布一个事件唤醒等待所的节点
对加锁次数减1,然后判断加锁数量是否还大于0
大于0,说明多次加锁(可重入的特性),那么重置锁过期时间
不大于0,说明最后一次释放锁,那么直接删除锁
获取等待队列头结点,然后唤醒它去进行加锁操作

点个在看你最好看
文章转载自程序猿西蒙,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
国产非关系型数据库 Eloqkv 初体验
JiekeXu
130次阅读
2025-04-10 23:51:35
融合Redis缓存的PostgreSQL高可用架构
梧桐
85次阅读
2025-04-08 06:35:40
Redis概要
听溪
38次阅读
2025-04-11 10:23:10
安装与配置Redis
鲁鲁
32次阅读
2025-04-11 10:26:10
Redis数据库——Cluster集群模式
编程Cookbook
28次阅读
2025-04-16 15:34:44
使用Jedis访问Redis数据库
怀念和想念
27次阅读
2025-04-11 15:08:30
Redis geo 实战:“附近的人”实现,打造社交的新维度
老王两点中
26次阅读
2025-04-11 09:02:30
Redis改协议内幕曝光!核心开发者亲述被“踢出局”,外部贡献者几乎全跑光了!
老鱼笔记
24次阅读
2025-04-17 10:41:56
Redis提供的持久化机制
luyingjun
22次阅读
2025-04-11 15:11:05
Redis
鲁鲁
21次阅读
2025-04-07 20:14:35