java中lock接口(如reentrantlock)相比synchronized提供更细粒度控制,支持可中断锁获取(lockinterruptibly)、带超时锁获取(trylock)、公平/非公平锁选择及多个condition精准唤醒,但需手动unlock确保资源释放。

Java 中的 Lock 接口(如 ReentrantLock)相比 synchronized 提供了更细粒度、更可控的锁机制,适合需要超时获取、可中断等待、公平锁、多条件变量等场景。
支持可中断的锁获取
synchronized 在等待锁时无法响应线程中断,而 Lock 的 lockInterruptibly() 方法允许线程在等待过程中被中断并抛出 InterruptedException,便于实现协作式取消逻辑。
- 调用
lock.lockInterruptibly()获取锁,若被中断则立即退出等待 - 需在
catch块中处理中断(如清理资源、退出循环) - 适用于长时间任务中需响应用户取消或超时控制的场景
支持带超时的锁获取
tryLock(long time, TimeUnit unit) 允许指定最多等待多久获取锁,避免无限阻塞。
- 返回
true表示成功获取锁,false表示超时未获取到 - 常用于避免死锁检测、资源争抢退让或实现“尽力而为”的并发策略
- 例如:尝试获取锁 100 毫秒,失败则记录日志并执行降级逻辑
支持公平锁与非公平锁选择
ReentrantLock 构造函数可传入 boolean fair 参数:
-
new ReentrantLock(true)启用公平模式,按等待顺序分配锁(吞吐量略低但避免饥饿) -
new ReentrantLock(false)(默认)为非公平锁,允许插队,吞吐量更高 - 公平性仅影响新请求锁的线程排队行为,不保证已持有锁的线程释放后立刻被唤醒
支持多个 Condition 实例实现精准唤醒
synchronized 只能配合 Object.wait()/notify(),所有等待者共用一个等待队列;Lock 可通过 newCondition() 创建多个独立的 Condition 对象。
- 每个
Condition维护自己的等待队列,可针对性地signal()或signalAll() - 典型应用:生产者-消费者模型中,分离“缓冲区非空”和“缓冲区非满”两个条件
- 必须在持有对应
Lock的前提下调用await()/signal(),否则抛出IllegalMonitorStateException
使用 Lock 时务必在 finally 块中调用 unlock(),防止因异常导致锁未释放。虽然比 synchronized 略显繁琐,但在需要高级并发控制时优势明显。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











