reentrantlock 通过 lockinterruptibly() 支持中断感知加锁,仅对等待锁的线程生效;需用布尔标记记录锁状态并在 finally 中安全解锁,catch 中执行资源清理,结合 condition 可实现可中断等待。

ReentrantLock 本身不自动响应线程中断,但配合 lockInterruptibly() 方法可实现中断感知的加锁,并在捕获 InterruptedException 后执行资源清理逻辑。
使用 lockInterruptibly() 响应中断
与 lock() 不同,lockInterruptibly() 在等待获取锁的过程中会响应中断:若线程被中断,会抛出 InterruptedException 并放弃抢锁,此时可立即释放已持有的其他资源或执行清理动作。
- 必须在 try-catch 中调用,且不能忽略中断状态(建议恢复中断标志:
Thread.currentThread().interrupt();) - 仅对“尚未获得锁、正在阻塞等待”的线程生效;若已持有锁,中断不会影响当前持有状态
- 示例场景:线程 A 正在等待锁,线程 B 调用
A.interrupt()→ A 抛出异常并退出等待
在 finally 块中确保 unlock()
无论是否因中断退出,只要成功获取了锁,就必须在 finally 块中调用 unlock(),避免死锁。注意:只有真正拿到锁后才需要解锁,因此需用布尔标记记录锁获取状态。
- 声明
boolean locked = false;,在lockInterruptibly()后设为true -
finally中判断if (locked) lock.unlock(); - 切勿在 catch 中直接 unlock —— 若未成功加锁就 unlock 会抛出
IllegalMonitorStateException
在 catch 块中执行定制化清理
捕获 InterruptedException 是执行业务级资源清理的关键入口。例如关闭文件句柄、回滚事务、释放网络连接等。
- 清理操作本身应尽量短小、无阻塞、不抛出新异常(或至少不传播)
- 若清理过程可能中断,可再次检查
Thread.interrupted()并提前退出 - 避免在清理中重新获取同一把锁,否则可能陷入死锁或递归等待
结合 Condition 实现可中断的等待
当使用 Condition.await() 等待条件时,同样支持中断:被中断会抛出 InterruptedException,并自动释放关联锁。此时也应在 catch 中做清理,并注意 await 前必须已持有锁。
- 调用
await()必须在lock()或lockInterruptibly()成功之后 - 中断后,Condition 不会自动重入等待,需由业务逻辑决定是否重试或退出
- 若需“中断即取消等待 + 清理 + 退出”,catch 中处理即可,无需额外同步控制
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











