必须在 finally 块中调用 unlock(),因为 reentrantlock 需手动释放锁,若仅在 try 末尾释放,异常会导致锁泄漏,引发阻塞或死锁;标准写法是 lock() 后立即进 try,finally 中 unlock()。

在 Java 中使用 ReentrantLock 时,必须在 finally 块中调用 unlock(),这是防止锁泄漏、保证线程安全的关键做法。
为什么必须在 finally 中释放锁
ReentrantLock 不像 synchronized 那样自动释放锁——它需要手动调用 lock() 和 unlock()。如果只在 try 块末尾释放,一旦中间发生异常(如 NullPointerException、IOException),unlock() 就不会执行,导致锁永远被持有,其他线程阻塞,最终可能引发死锁或系统假死。
标准写法:try-lock + finally-unlock
正确模式如下:
Lock lock = new ReentrantLock();
lock.lock();
try {
// 临界区操作(可能抛异常)
doSomething();
} finally {
lock.unlock(); // 无论是否异常,一定执行
}
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
常见错误与规避方式
- 把 unlock() 放在 try 或 catch 里:无法覆盖所有异常路径,锁可能未释放
-
在 lock() 前就进入 try 块:若
lock()失败(如被中断),unlock()会抛IllegalMonitorStateException;应确保只在成功加锁后才进 try -
重复 unlock():同一个线程多次调用
unlock()超出加锁次数,会抛异常;建议配合isHeldByCurrentThread()调试(仅用于开发,不建议生产判断)
进阶建议:使用 tryLock 避免无限等待
若业务允许失败重试或超时处理,可用 tryLock() 替代 lock():
if (lock.tryLock()) {
try {
doSomething();
} finally {
lock.unlock();
}
} else {
// 获取锁失败,走降级逻辑
这样既避免线程无限阻塞,又保持了 finally 释放的可靠性。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










