用tryLock避免死锁的核心是主动放弃而非无限等待,通过立即返回或限时等待机制打破循环等待条件,并结合固定顺序加锁与失败回退策略实现安全并发。

用 tryLock 避免死锁的核心是:不无限等待,主动放弃并回退,打破“循环等待”条件。
理解 tryLock 如何切断死锁链
ReentrantLock.tryLock() 有两种常用重载:
-
tryLock():立即返回,获取到锁返回true,否则立刻返回false; -
tryLock(long timeout, TimeUnit unit):最多等待指定时间,超时未获锁则返回false。
与 lock()(会一直阻塞直到拿到锁)不同,tryLock 让线程能“试一下,不行就走”,从而避免多个线程互相僵持。
按固定顺序加锁 + tryLock 回退(推荐做法)
死锁常见于多个线程以不同顺序申请多把锁。解决思路是:约定锁的获取顺序,并配合 tryLock 实现失败回退。
例如操作两个账户转账(需同时锁定 from 和 to 账户):
- 规定:总是先锁 id 小的账户,再锁 id 大的;
- 用
tryLock()尝试获取两把锁; - 只要任意一把没拿到,就立即释放已持有的锁,稍后重试或报错。
代码示意:
public void transfer(Account from, Account to, int amount) {
// 按 id 升序确定加锁顺序
Account first = from.getId()
设置超时 + 明确释放策略(防资源泄漏)
使用带超时的 tryLock 更稳妥,尤其在锁竞争激烈或外部依赖不确定时:
- 超时时间不宜过短(导致频繁失败),也不宜过长(延迟问题暴露);建议从 100ms 起步,按实际场景调整;
- 必须用
try-finally或try-with-resources(配合自定义锁包装)确保锁被释放; - 返回
false时,要记录日志或触发告警,便于定位高并发瓶颈。
配合中断响应,提升系统可控性
ReentrantLock 支持响应线程中断,可在等待中止任务:
- 用
tryLock(1, TimeUnit.SECONDS)代替无界等待; - 若线程被中断,抛出
InterruptedException,此时应清理状态、释放已持锁、退出; - 避免在持有锁时忽略中断,防止“锁住了却不知道该停”。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











