ReentrantLock的tryLock(timeout)方法支持限时获取锁,成功返回true,超时返回false且不阻塞;需配合finally中unlock确保释放,并注意公平锁与非公平锁的性能及饥饿权衡。

ReentrantLock 提供了 tryLock(long timeout, TimeUnit unit) 方法,专门用于实现限时等待获取锁的业务场景。
使用 tryLock(timeout) 实现限时获取锁
与 lock() 的阻塞式获取不同,tryLock 在指定时间内尝试获取锁:成功则返回 true,超时未获取到则返回 false,不会阻塞线程。适合对响应时间敏感、需避免长时间卡死的业务。
- 必须搭配
isHeldByCurrentThread()或unlock()的安全调用(通常用finally块保证释放) - 超时单位支持
TimeUnit.SECONDS、MILLISECONDS等,推荐显式写出单位,避免歧义 - 若锁已被其他线程持有,当前线程会最多等待指定时长,期间可能被中断(抛出
InterruptedException)
典型业务代码结构
以下是一个安全、可落地的写法示例:
ReentrantLock lock = new ReentrantLock();
boolean isLocked = false;
try {
// 尝试最多等待 3 秒
isLocked = lock.tryLock(3, TimeUnit.SECONDS);
if (isLocked) {
// 成功获取锁,执行临界区逻辑
doCriticalWork();
} else {
// 获取锁失败,走降级或补偿逻辑(如返回错误、重试、记录告警等)
handleLockTimeout();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 恢复中断状态
handleInterrupted();
} finally {
if (isLocked) {
lock.unlock();
}
}
注意公平性与性能权衡
如果构造 ReentrantLock 时传入 true(即公平锁),tryLock(timeout) 仍遵循 FIFO 队列顺序,但会严格检查等待队列头部是否是当前线程——这会略微增加开销。非公平锁(默认)下,它仍可能插队成功(即在等待前先 CAS 尝试一次),响应更快,但可能加剧“饥饿”。
- 高并发且对延迟敏感的场景,建议用默认非公平锁 + 合理 timeout
- 强一致性要求(如金融类排队操作),再考虑公平锁,并充分压测 timeout 行为
- 不要在循环中无休止地调用
tryLock(如 while(!tryLock())),容易空转耗 CPU;应配合退避策略或改用条件等待
替代思路:结合 Condition 做更精细的等待控制
如果业务不只是“等锁”,而是“等锁 + 等某个条件成立”,可配合 Condition 使用 awaitNanos 或 awaitUntil。例如:
- 先用
tryLock获取锁 - 再用
condition.awaitNanos(remainingNanos)等待业务条件,同时动态计算剩余超时时间 - 每次唤醒后重新校验条件和锁状态,形成带时限的条件等待闭环
这种方式比单纯 tryLock 更灵活,适用于“获取锁后还需等待资源就绪”的复合场景。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











