// 方案2:不使用看门狗(适合短时间固定业务) lock.tryLock(waitTime, 30, TimeUnit.SECONDS);
// 方案3:完全禁用看门狗(明确业务执行时间) lock.tryLock(waitTime, 10, TimeUnit.SECONDS); 这个不是完全一样的
你说得对,这两行代码在逻辑上完全一致,只是参数值不同。我的注释确实造成了误解。让我重新澄清:
Redisson 的看门狗机制规则
核心规则:
只有两种情况会启用看门狗:
- 不指定
leaseTime参数(使用两个参数的tryLock) - 指定
leaseTime = -1
其他情况(指定任何正的 leaseTime 值)都不会启用看门狗。
正确对比:
JAVA
// 方案A:使用看门狗机制(自动续期)
lock.tryLock(waitTime, -1, TimeUnit.SECONDS); // 或 lock.tryLock(waitTime, TimeUnit.SECONDS)
// 方案B:禁用看门狗机制(固定租期)
lock.tryLock(waitTime, 30, TimeUnit.SECONDS); // 30秒后自动过期,不续期
更明确的分类示例:
1. 使用看门狗(自动续期)
JAVA
// 方式1:两个参数方法,默认启用看门狗
lock.tryLock(3, TimeUnit.SECONDS);
// 方式2:三个参数,显式设为-1
lock.tryLock(3, -1, TimeUnit.SECONDS);
- 看门狗默认30秒超时
- 每10秒自动续期一次
- 适用于执行时间不确定的业务
- 必须手动解锁,否则锁会一直存在
2. 禁用看门狗(固定租期)
JAVA
// 固定租期10秒
lock.tryLock(3, 10, TimeUnit.SECONDS);
// 固定租期30秒
lock.tryLock(3, 30, TimeUnit.SECONDS);
// 固定租期60秒
lock.tryLock(3, 60, TimeUnit.SECONDS);
- 无论设多少秒,都不启用看门狗
- 指定时间后自动释放
- 适用于执行时间可预估的业务
- 即使不手动解锁,也会在租期后自动释放
代码示例对比:
JAVA
public class LockExample {
/**
* 使用看门狗(自动续期)
* 适合:长时间任务,如定时任务处理大量数据
*/
public void processWithWatchdog() {
RLock lock = redisson.getLock("long-task");
try {
if (lock.tryLock(3, -1, TimeUnit.SECONDS)) {
// 长时间任务,看门狗会每10秒自动续期
processLongTask(); // 可能执行几分钟
}
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
/**
* 禁用看门狗(固定租期)
* 适合:短时间确定性任务
*/
public void processWithoutWatchdog() {
RLock lock = redisson.getLock("short-task");
try {
// 最多等待1秒,锁定3秒后自动释放
if (lock.tryLock(1, 3, TimeUnit.SECONDS)) {
processShortTask(); // 保证3秒内完成
// 可以不手动解锁,3秒后会自动释放
}
} catch (Exception e) {
// 即使业务异常,锁也会在3秒后自动释放
}
}
}
重要区别总结:
| 特性 | 使用看门狗 (leaseTime=-1) |
禁用看门狗 (leaseTime>0) |
|---|---|---|
| 自动续期 | ✅ 是,每10秒自动续期 | ❌ 否,固定时间后过期 |
| 默认超时 | 30秒 | 自定义的 leaseTime |
| 适用场景 | 执行时间不确定的任务 | 执行时间可预估的短任务 |
| 释放要求 | 必须手动解锁 | 可手动解锁,也会自动过期 |
| 防死锁 | 需确保finally中解锁 | 有超时保护,但仍建议解锁 |
| 网络故障 | 看门狗停止续期,锁在30秒后释放 | 锁在 leaseTime 后释放 |
最佳实践建议:
不确定执行时间的业务,使用看门狗,并在finally中确保解锁:
JAVAlock.tryLock(waitTime, -1, TimeUnit.SECONDS);确定短时间的业务,使用固定租期:
JAVA// 根据业务最长时间设置,通常加一些缓冲 int estimatedTime = 5; // 预估5秒完成 int buffer = 2; // 2秒缓冲 lock.tryLock(waitTime, estimatedTime + buffer, TimeUnit.SECONDS);
感谢指出,之前注释的表述确实容易引起误解。核心是:任何正数的 leaseTime 都会禁用看门狗,只有 -1 或不指定时才启用。