【Redisson】四.可重入锁-可重入加锁源码
前言
主要介绍Redisson可重入锁,实现可可重入加锁的源码解析
源码分析
这里回头看看加锁的代码如下
<T> RFuture<T> tryLockInnerAsync(long leaseTime, TimeUnit unit, long threadId, RedisStrictCommand<T> command) { internalLockLeaseTime = unit.toMillis(leaseTime); return evalWriteAsync(getName(), LongCodec.INSTANCE, command, "if (redis.call('exists', KEYS[1]) == 0) then " + "redis.call('hincrby', KEYS[1], ARGV[2], 1); " + "redis.call('pexpire', KEYS[1], ARGV[1]); " + "return nil; " + "end; " + "if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " + "redis.call('hincrby', KEYS[1], ARGV[2], 1); " + "redis.call('pexpire', KEYS[1], ARGV[1]); " + "return nil; " + "end; " + "return redis.call('pttl', KEYS[1]);", Collections.singletonList(getName()), internalLockLeaseTime, getLockName(threadId)); }
其中lua脚本中的第二个分支
//如果当前线程已经获取到锁 "if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " //将锁表示的对象的值,进行 加1 "redis.call('hincrby', KEYS[1], ARGV[2], 1); " + //设置锁的过期时间为 internalLockLeaseTime leaseTime(默认为30000毫秒)
"redis.call('pexpire', KEYS[1], ARGV[1]); " + "return nil; " +
这里回过头看redisson加锁实现的hash数据结构
此时的value的值1, 就是和锁的可重入有关,表示持有锁的线程对当前锁的重入次数
测试demo
这里执行一段代码测试下Reddsson可重入锁。同时观察下Redis中value值的变化
@ApiOperation(value="redis可重入锁测试") @GetMapping(value = "/reentrantTest") public BaseOutput<?> redisDemo(){ log.info("当前线程Id:{}",Thread.currentThread().getId()); RLock lock = redissonClient.getLock("lock"); log.info("第1次加锁"); lock.lock(); log.info("第2次加锁"); lock.lock(); log.info("第1次释放锁"); lock.unlock(); log.info("第2次释放锁"); lock.unlock(); return BaseOutput.success(); }
1.第一次加锁redis value值为1
2.第二次加锁redis value值为2
3.第一次释放锁,value值减一,value为1
4.第二次释放锁,value值减一,锁完全释放,redis key被删除