水煮Redisson(十六)-聊聊等待时间、持有时间、看门狗时间

1,761 阅读2分钟

前言

单独设置这一章节,是因为这几个重要参数:waitTime、leaseTime和lockWatchdogTimeout,在后续各种锁的实现中,频繁出现,需要提请弄清楚,否则会带来不小的困扰。

几个定义

先说说这几个超时时间,接口中的定义如下

 /**
     * Tries to acquire the lock with defined <code>leaseTime</code>.
     * Waits up to defined <code>waitTime</code> if necessary until the lock became available.
     *
     * Lock will be released automatically after defined <code>leaseTime</code> interval.
     *
     * @param waitTime the maximum time to acquire the lock
     * @param leaseTime lease time
     * @param unit time unit
     * @return <code>true</code> if lock is successfully acquired,
     *          otherwise <code>false</code> if lock is already set.
     */
    RFuture<Boolean> tryLockAsync(long waitTime, long leaseTime, TimeUnit unit);
  1. waitTime:等待时间;在锁状态变为可持有之前,等待的时间,如果在这个时间内,锁一直被其他客户端线程持有,则放弃等待,返回失败;
  2. leaseTime:持有时间;客户端获取到锁之后的最长持有时间,如果设置此参数为10秒,则10秒后,如果此客户端不释放锁,则有redis自行释放,以免造成死锁。
  3. lockWatchdogTimeout:看门狗时间;如果客户端不设定持有时间,则持有时间会被设置为看门狗时间,默认为30秒。

这里说明一下,凡是leaseTime设置为-1的,默认都会被设置为看门狗时间,看这里的实现:

    private <T> RFuture<Long> tryAcquireAsync(long leaseTime, TimeUnit unit, long threadId) {
        if (leaseTime != -1) {
            return tryLockInnerAsync(leaseTime, unit, threadId, RedisCommands.EVAL_LONG);
        }
		// leaseTime等于-1,这里将其设置为看门狗时间
        RFuture<Long> ttlRemainingFuture = tryLockInnerAsync(commandExecutor.getConnectionManager()
		.getCfg().getLockWatchdogTimeout(), TimeUnit.MILLISECONDS, threadId, RedisCommands.EVAL_LONG);
        ttlRemainingFuture.onComplete((ttlRemaining, e) -> {
            if (e != null) {
                return;
            }

            // lock acquired
            if (ttlRemaining == null) {
                scheduleExpirationRenewal(threadId);
            }
        });
        return ttlRemainingFuture;
    }

看门狗时间设置

看门狗的默认时间是30秒,在org.redisson.config.Config类中设置。这个参数仅仅在客户端线程请求锁,没有填写持有时间参数时生效。

    private long lockWatchdogTimeout = 30 * 1000;

    /**
     * This parameter is only used if lock has been acquired without leaseTimeout parameter definition. 
     * Lock expires after <code>lockWatchdogTimeout</code> if watchdog 
     * didn't extend it to next <code>lockWatchdogTimeout</code> time interval.
     * <p>  
     * This prevents against infinity locked locks due to Redisson client crush or 
     * any other reason when lock can't be released in proper way.
     * <p>
     * Default is 30000 milliseconds
     * 
     * @param lockWatchdogTimeout timeout in milliseconds
     * @return config
     */
    public Config setLockWatchdogTimeout(long lockWatchdogTimeout) {
        this.lockWatchdogTimeout = lockWatchdogTimeout;
        return this;
    }

    public long getLockWatchdogTimeout() {
        return lockWatchdogTimeout;
    }