前言
单独设置这一章节,是因为这几个重要参数: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);
- waitTime:等待时间;在锁状态变为可持有之前,等待的时间,如果在这个时间内,锁一直被其他客户端线程持有,则放弃等待,返回失败;
- leaseTime:持有时间;客户端获取到锁之后的最长持有时间,如果设置此参数为10秒,则10秒后,如果此客户端不释放锁,则有redis自行释放,以免造成死锁。
- 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;
}