无异常抛出场景下lock操作搭配try-finally使用是否仍有必要?
Lock加解锁规范问题解答
结论
哪怕你完全确定try代码块内不会抛出任何异常,也应当严格遵守用try-finally包裹锁操作的官方规范,没有例外。
核心原因
- 代码是持续迭代的,你现阶段写的
x++确实不会抛出异常,但后续维护过程中很可能有人在代码块内新增带异常风险的逻辑,比如方法调用、参数校验、类型转换等。如果没有try-finally结构,一旦后续新增的代码抛出异常,锁会直接泄漏,所有等待该锁的线程都会永久阻塞,这类线上死锁问题排查成本极高。 - 就算你能保证代码永远不修改,JVM层面仍然可能抛出
VirtualMachineError类的异常,比如OOM、栈溢出等,这类错误不受普通异常逻辑限制,但finally块仍然可以保证在极端场景下锁被正常释放,避免整个应用彻底不可用。 - 统一编码规范可以降低心智负担,每次加锁后直接套try-finally,不需要每次花精力判断代码块会不会抛异常,也能避免偶尔漏写释放逻辑的失误,同时其他开发者一看就能明确锁的释放逻辑是安全的,可读性更高。
反例风险
如果不使用try-finally,代码写成如下形式:
mutex.lock(); x++; mutex.unlock();
看似没问题,但只要后续把x++修改为x = Integer.parseInt(input)这类带异常风险的逻辑,一旦入参格式错误抛出NumberFormatException,mutex.unlock()就永远不会执行,直接造成锁泄漏。
官方规范之所以明确要求这种写法,本质是因为锁泄漏的风险和损失远大于多写几行try-finally的成本,完全没必要为了省代码冒死锁的风险。
内容的提问来源于stack exchange,提问作者QenBau
相关产品推荐
相关产品推荐

