使用ReentrantLock避免饥饿需启用公平模式(new ReentrantLock(true))、锁内仅执行快速操作、用tryLock设置超时、并在finally中确保unlock。

使用 ReentrantLock 避免饥饿,关键在于启用其公平性(fairness)机制,并配合合理的锁使用习惯,而非仅依赖默认的非公平模式。
启用公平锁模式
默认情况下,ReentrantLock 是非公平的,新线程可能插队获取锁,导致等待时间长的线程始终得不到执行机会。开启公平模式后,锁按请求顺序分配,显著降低饥饿概率。
- 创建锁时传入
true:new ReentrantLock(true) - 公平锁会维护一个 FIFO 等待队列,确保先请求的线程优先获得锁
- 注意:公平锁吞吐量略低,但对响应性与可预测性要求高的场景更合适(如定时任务、资源池管理)
避免锁内执行耗时操作
即使启用了公平锁,若持有锁期间做大量计算、I/O 或等待,仍会让后续线程长时间阻塞——这本质是“逻辑饥饿”,与锁机制无关。
- 锁内只做必要、快速的操作(如状态更新、简单校验)
- 耗时逻辑(如网络调用、文件读写)移出临界区
- 示例:不要在锁中调用
Thread.sleep()或httpClient.execute()
使用带超时的锁获取
通过 tryLock(long timeout, TimeUnit unit) 主动控制等待上限,防止无限期阻塞,便于实现退避、重试或降级策略。
立即学习“Java免费学习笔记(深入)”;
- 获取失败可记录日志、触发告警,或切换到无锁路径(如使用 CAS 或副本)
- 结合指数退避重试,比死等更健壮
- 例如:
if (lock.tryLock(100, TimeUnit.MILLISECONDS)) { ... } else { /* 处理获取失败 */ }
及时释放锁并确保异常安全
未正确释放锁会导致其他线程永久阻塞,是最直接的饥饿成因。
- 必须在
finally块中调用unlock() - 不要把
unlock()放在try或catch中——异常可能跳过它 - 推荐写法:始终用 try-finally 包裹 lock/unlock


















