reentrantlock 的 lockinterruptibly() 方法支持可中断锁获取,线程等待时响应中断并抛出 interruptedexception;需在 try-catch 中调用,catch 中处理中断并恢复中断状态,finally 中 unlock;相比 synchronized 具备中断响应、超时获取及 condition 协作等优势。

在 Java 中,使用 ReentrantLock 实现可中断的任务执行逻辑,核心在于配合 lockInterruptibly() 方法 —— 它允许线程在等待锁的过程中响应中断信号,从而避免死等、提升任务可控性。
用 lockInterruptibly() 替代 lock() 获取锁
lockInterruptibly() 是实现可中断的关键。与无条件阻塞的 lock() 不同,它会在等待锁时检查线程是否被中断;一旦发现中断状态,立即抛出 InterruptedException,并放弃获取锁。
- 调用前确保当前线程未被中断(可选检查
Thread.interrupted()) - 必须在
try块中调用,并在catch中处理中断(如清理资源、退出任务) - 成功获取锁后,仍需在
finally中显式unlock()
完整可中断任务模板
一个典型结构包括:尝试获取锁 → 执行业务逻辑 → 异常处理 → 确保释放锁。中断发生时,不继续执行任务,而是快速退出。
ReentrantLock lock = new ReentrantLock();
...
try {
lock.lockInterruptibly(); // 可中断地获取锁
try {
// 执行受保护的临界区逻辑
doWork();
} finally {
lock.unlock(); // 必须释放锁
}
} catch (InterruptedException e) {
// 中断发生:清理、记录、退出任务
Thread.currentThread().interrupt(); // 恢复中断状态(推荐)
System.out.println("任务被中断,退出执行");
}
配合 interrupt() 主动终止等待中的任务
当某个任务长时间卡在 lockInterruptibly() 上,外部可通过 thread.interrupt() 触发其响应中断。注意以下几点:
- 仅对处于 WAITING 或 TIMED_WAITING 状态的线程有效(
lockInterruptibly()正是让线程进入这种状态) - 若线程已获得锁并正在执行业务逻辑,则需在业务代码中定期检查
Thread.interrupted()并主动退出 - 不要忽略
InterruptedException,也不应简单吞掉;通常应恢复中断状态并退出当前任务
与 synchronized 对比的优势
synchronized 无法响应中断(等待进入同步块时不可中断),而 ReentrantLock.lockInterruptibly() 提供了更精细的线程协作能力:
- 支持超时获取锁(
tryLock(long, TimeUnit)),进一步增强可控性 - 可与
Condition配合实现更复杂的等待/通知机制,并同样支持中断 - 适合需要取消长时等待、实现协作式关闭或构建响应式任务调度器的场景
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











