【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被删除

 

  

posted @ 2022-02-06 18:08  听风是雨  阅读(248)  评论(0编辑  收藏  举报
/* 看板娘 */