Redisson-lock看门狗原理

Redisson-lock看门狗原理

8. 分布式锁和同步器 · redisson/redisson Wiki · GitHub

默认-1

image-20220831162445593

传入自己的时间(此处为10) 不会执行看门狗,不等于-1,如果是默认的话,等于-1

image-20220831162321988

进入tryLockInnerAsync,发现直接执行脚本

<T> RFuture<T> tryLockInnerAsync(long waitTime, long leaseTime, TimeUnit unit, long threadId, RedisStrictCommand<T> command) {
    return this.evalWriteAsync(this.getRawName(), 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(this.getRawName()), new Object[]{unit.toMillis(leaseTime), this.getLockName(threadId)});
}

image-20220831163354777


image-20220831164632188

protected RFuture<Boolean> renewExpirationAsync(long threadId) {
    return this.evalWriteAsync(this.getRawName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN, "if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then redis.call('pexpire', KEYS[1], ARGV[1]); return 1; end; return 0;", Collections.singletonList(this.getRawName()), this.internalLockLeaseTime, this.getLockName(threadId));
}

  1. 锁的自动续期,如果业务超长,运行时间自动给锁续上新的30秒。不用担心业务时间长。
  2. 加锁的任务只要运行完成,就不会给当前锁续期,即使不手动删锁。锁默认30秒后删除

lock.lock(10, TimeUnit.SECONDS);

  • 10秒钟自动解锁,自动解锁时间一定要大于业务时间

问题:lock.lock();在锁时间到了以后,不会自续期

  • 1、如果我们传递了锁的超时时间,就发送给redis脚本,进行占锁,默认超时时间就是我们设置的时间

  • 2、如果我们未指定锁的超时时间,就使用 30*1000 (LockWatchdogTimeout看门狗的默认时间);
    只要占锁成功,leaseTime=-1就会启动一个定时任务

    • [重新给锁设置过期时间,新的过期时间就是看门狗的默认时间30s],每隔10s都会自动续期30s
      internalLockLeaseTime(看门狗时间)/3,10s
@ResponseBody
@GetMapping("/hello")
public String hello(){
    //1、获取一把锁,只要锁的名字一样,就是同一把锁
    RLock lock = redissonClient.getLock("myLock");
    //2、加锁
    lock.lock();//阻塞式等待,没拿到锁,一直等待。默认加锁30秒
    
    //最佳实战
    //       lock.lock(10, TimeUnit.SECONDS);//10秒钟自动解锁,自动解锁时间一定要大于业务时间
    // 省掉了整个续期操作。手动解锁
    try {
        System.out.println("加锁成功,执行业务"+Thread.currentThread().getId());
        Thread.sleep(30000);
    } catch (InterruptedException e) {

    } finally {
        //3、解锁,假设解锁代码没有运行,redisson会不会出现死锁
        System.out.println("释放锁"+Thread.currentThread().getId());
        lock.unlock();
    }
    return "hello";
}

image-20220831165516475

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值