lock接口提供显式锁管理,支持可中断、超时、公平性选择及多condition通信,比synchronized更灵活健壮,但需手动配对lock()与unlock()避免泄漏。

Lock 接口让线程同步从“自动托管”变成“自主掌控”,关键在于显式获取与释放、可中断、可超时、可绑定条件变量——这些是 synchronized 做不到的。
锁的获取和释放可以分离,适配复杂业务流程
同步块必须成对出现在同一作用域内,而 Lock 允许 lock() 和 unlock() 分散在不同逻辑分支中,只要确保最终释放即可。典型写法是:在 try 前加锁,finally 中解锁,避免因异常导致死锁。
- 加锁后做判断,满足条件提前返回,仍能保证解锁
- 跨方法协作时,可在入口加锁、出口解锁(需谨慎设计生命周期)
- 配合资源池、状态机等场景,锁可随状态流转而动态管理
支持响应中断和设置超时,提升系统健壮性
当线程等待锁太久或被外部取消时,synchronized 无法响应;Lock 提供了两种主动控制方式:
-
lockInterruptibly():等待过程中收到中断信号,立刻抛出InterruptedException,便于上层统一处理取消逻辑 -
tryLock(long, TimeUnit):指定最多等待多久,超时返回false,可用于实现重试机制或降级策略
例如网络请求+本地缓存更新场景,可设 200ms 超时抢锁,失败则直接读旧缓存,不阻塞主流程。
可构建公平锁与非公平锁,按需调节调度策略
ReentrantLock 构造时传入 true 即启用公平模式,线程按等待顺序排队获取锁;默认是非公平模式,允许插队以提升吞吐量。
- 高竞争 + 低延迟敏感场景(如日志聚合),用公平锁减少饥饿
- 多数普通业务(如订单扣减),非公平锁性能更好,JVM 也默认如此
-
synchronized没有公平性选项,底层实现固定为非公平
配合 Condition 实现精准线程通信
一个 Lock 可创建多个 Condition 对象,分别对应不同等待条件(比如“库存不足”“支付超时”),比 Object.wait()/notify() 更安全、更解耦。
- 避免
notifyAll()唤醒所有线程造成的无效竞争 - 每个 Condition 独立维护等待队列,唤醒只影响相关线程组
- 典型应用:生产者-消费者中区分“空”和“满”两个条件
不复杂但容易忽略:Lock 是接口,必须搭配具体实现(如 ReentrantLock)使用;且每次 lock() 都要配对 unlock(),否则会导致锁泄漏——这是灵活性带来的责任。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











