Redission 对比isHeldByCurrentThread()和unlock()
- Redission版本:
<dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.51.0</version>
</dependency>
- isHeldByCurrentThread会发送redis hash exists命令,参数为锁的key和value
(HEXISTS)
- unlock会发送如下脚本命令,包括前置判断和解锁操作。
-- 获取锁状态缓存值(避免重复计算)
local val = redis.call('get', KEYS[3]);
-- 如果状态值已存在,直接返回数值结果
if val ~= false then return tonumber(val);
end;
-- 检查锁是否属于当前线程(通过线程标识验证)
if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then -- 锁不属于当前线程,返回nil表示解锁失败return nil;
end;
-- 减少锁的重入计数(原子操作)
local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1);
-- 判断重入计数
if (counter > 0) then -- 重入计数仍大于0(锁未完全释放)-- 更新锁的过期时间(续期)redis.call('pexpire', KEYS[1], ARGV[2]); -- 设置状态缓存值为0(表示部分解锁)redis.call('set', KEYS[3], 0, 'px', ARGV[5]); -- 返回0表示锁未完全释放return 0;
else -- 重入计数归零(锁完全释放)-- 删除锁键redis.call('del', KEYS[1]); -- 发布解锁消息(通知等待线程)redis.call(ARGV[4], KEYS[2], ARGV[1]); -- 设置状态缓存值为1(表示完全解锁)redis.call('set', KEYS[3], 1, 'px', ARGV[5]); -- 返回1表示锁已完全释放return 1;
end;
结论:既然都产生IO,unlock也包含isHeldByCurrentThread的功能,不如直接调用unlock,放弃isHeldByCurrentThread前置判断。