用 trylock() 是避免死锁最实用方式之一:它主动试探加锁,超时失败即放弃,打破循环等待;需设合理超时、finally 释放已持锁、配合固定顺序加锁更稳妥。

用 ReentrantLock 的 tryLock() 是避免死锁最实用的方式之一——它不盲目等待,而是主动“试探”能否获取锁,超时或失败就及时放弃,从而打破死锁的循环等待条件。
用带超时的 tryLock() 主动退出争抢
死锁常发生在多个线程按不同顺序申请同一组锁(比如线程 A 先锁 obj1 再锁 obj2,线程 B 反过来),而 tryLock(long, TimeUnit) 能让线程在拿不到锁时直接返回,而不是无限阻塞。
关键做法:
- 始终为
tryLock()指定合理超时时间(如 100ms),避免“等一会儿”变成“等永远” - 获取失败时,必须释放已持有的所有锁(需用
finally块确保) - 放弃后可重试、降级处理,或抛出业务异常,不硬扛
按固定顺序加锁 + tryLock() 双保险
即使用了 tryLock(),如果两个线程仍以不同顺序尝试同一组锁,仍可能反复冲突甚至活锁。更稳妥的做法是:约定资源编号,总是按编号升序(或降序)申请锁。
例如有 lockA 和 lockB,统一规定“先 tryLock lockA,再 tryLock lockB”。配合 tryLock(),就能从根源上消除循环等待可能。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
示例逻辑:
if (lockA.tryLock(100, MILLISECONDS)) {
try {
if (lockB.tryLock(100, MILLISECONDS)) {
try {
// 执行临界区操作
} finally {
lockB.unlock();
}
} else {
// lockB 没拿到,不继续,直接释放 lockA
}
} finally {
lockA.unlock();
}
}
用 tryLock() 实现可中断的协作式加锁
标准 synchronized 不响应中断,而 ReentrantLock.tryLock() 可与 Thread.interrupted() 配合,让线程在等待锁时能被外部中断,进一步提升系统可控性。
建议写法:
- 在循环中调用
tryLock(),每次失败前检查是否被中断 - 若检测到中断,清理资源并退出,不重试
- 避免在锁未获取成功时就修改共享状态
注意 unlock() 必须放在 finally 块中
tryLock() 成功后,锁必须显式释放;一旦因异常跳过 unlock(),就会造成锁泄漏,间接引发后续线程饥饿甚至假死锁。
正确结构:
if (lock.tryLock(50, MILLISECONDS)) {
try {
// 临界区操作
} finally {
lock.unlock(); // 无论是否异常,都释放
}
} else {
// 处理获取失败:日志、重试、降级等
}
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










