核心区别在于对中断的响应:lock() 忽略中断直至获锁;lockInterruptibly() 在等待中收到中断即抛 InterruptedException 并退出,且若调用前已中断则直接抛异常,适用于需可控退出的场景。

核心区别在于对线程中断的响应方式:`lock()` 完全忽略中断,必须等到锁可用才继续;`lockInterruptibly()` 在等待锁的过程中一旦被中断,立即抛出 InterruptedException 并退出等待。
行为表现差异
当锁已被占用、当前线程需等待时:
-
lock():线程进入 WAITING 状态,不响应任何interrupt()调用,会一直等下去,直到获取到锁为止 -
lockInterruptibly():线程同样等待,但只要在 park 过程中收到中断信号,立刻唤醒并抛出异常,不再尝试获取锁 - 若调用
lockInterruptibly()前线程已处于中断状态(Thread.interrupted()返回 true),方法不会尝试加锁,直接抛出InterruptedException
适用场景不同
选择哪个方法,取决于你是否需要“可控退出”能力:
- 用
lock():适合内部资源协调、短临界区、或确定不会长期阻塞的场景,逻辑简单,无需处理中断 - 用
lockInterruptibly():适合对外提供服务、支持取消/超时/优雅关闭的场景,例如:
– Web 请求超时后中断后台锁等待
–Future.cancel(true)触发任务终止
– 主控线程调用worker.interrupt()协作式关闭
异常处理要求严格
lockInterruptibly() 必须配合规范的异常处理,否则容易丢失中断语义:
立即学习“Java免费学习笔记(深入)”;
- 必须放在
try块中,不能裸调用 -
catch (InterruptedException)中不能吞掉异常,应恢复中断状态:Thread.currentThread().interrupt(); -
unlock()必须放在finally块中,并建议加if (lock.isHeldByCurrentThread())防御性判断
和 synchronized 的对比
这和内置锁也有对应关系:
-
synchronized块的行为类似lock():进入 monitor wait 时忽略中断,只有退出同步块后才可能响应 - 没有原生的“可中断 synchronized”,所以需要中断感知能力时,
lockInterruptibly()是更可控的选择


















