直接看lua代码:
1protected RFuture<Boolean> unlockInnerAsync(long threadId) {2 return commandExecutor.evalWriteAsync(getName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,
3 // 判断锁key值是否存在
4 "if (redis.call('exists', KEYS[1]) == 0) then " +
5 "redis.call('publish', KEYS[2], ARGV[1]); " +
6 "return 1; " +
7 "end;" +
8 // 判断当前机器、当前线程id对应的key是否存在
9 "if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then " +
10 "return nil;" +
11 "end; " +
12 // 计数器数量-1 可重入锁
13 "local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1); " +
14 // 如果计数器大于0,说明还在持有锁
15 "if (counter > 0) then " +
16 "redis.call('pexpire', KEYS[1], ARGV[2]); " +
17 "return 0; " +
18 "else " +
19 // 使用del指令删除key
20 "redis.call('del', KEYS[1]); " +
21 "redis.call('publish', KEYS[2], ARGV[1]); " +
22 "return 1; "+
23 "end; " +
24 "return nil;",
25 Arrays.<Object>asList(getName(), getChannelName()), LockPubSub.unlockMessage, internalLockLeaseTime, getLockName(threadId));
26}
总结
一图总结:
01_redission 可重入锁实现原理.jpg