ReentrantLock的tryLock(long timeout, TimeUnit unit)方法可在指定时间内尝试获取锁,超时返回false避免无限等待;成功返回true需手动unlock,false可执行降级逻辑,中断则抛InterruptedException。

ReentrantLock 提供了 tryLock(long timeout, TimeUnit unit) 方法,可以在指定时间内尝试获取锁,超时未获取到则返回 false,从而避免无限等待。
使用 tryLock 设置超时获取锁
这是最直接的方式。与无参的 lock() 不同,带超时的 tryLock 不会阻塞线程,而是最多等待指定时间:
- 返回
true:成功获取锁,后续需手动调用unlock() - 返回
false:超时未获取到锁,线程可执行降级逻辑(如重试、记录日志、返回错误等) - 抛出
InterruptedException:等待过程中线程被中断,需正确处理异常
示例代码:
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。
ReentrantLock lock = new ReentrantLock();
boolean isLocked = false;
try {
isLocked = lock.tryLock(3, TimeUnit.SECONDS);
if (isLocked) {
// 执行临界区操作
System.out.println("获取锁成功");
} else {
System.out.println("获取锁超时,跳过操作");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 恢复中断状态
System.out.println("等待锁时被中断");
} finally {
if (isLocked) {
lock.unlock();
}
}
注意公平性与超时行为的关系
ReentrantLock 构造时若启用公平模式(new ReentrantLock(true)),tryLock 超时等待仍遵循队列顺序;但公平锁本身会降低吞吐量,且超时判断发生在排队等待期间,不保证“立即失败”。非公平锁下,tryLock 可能先尝试快速抢占(CAS),失败后再进入等待队列——这对响应时间更友好。
立即学习“Java免费学习笔记(深入)”;
避免常见陷阱
-
必须检查返回值:不能假设
tryLock一定成功,漏判false可能导致临界区逻辑被意外执行 -
解锁前务必确认已加锁:只在
isLocked == true时调用unlock(),否则抛IllegalMonitorStateException -
超时单位要明确:避免用错时间单位(如把毫秒传成秒),推荐始终使用
TimeUnit枚举 - 不要在循环中盲目重试:若需重试,应加入退避策略(如指数退避),防止资源空转或雪崩
不复杂但容易忽略的是:超时只是控制等待时长,并不解决锁竞争的根本问题。合理设计锁粒度、减少临界区长度、考虑无锁结构(如 AtomicInteger)或读写分离,往往比依赖超时更有效。

















