synchronized在异常时自动释放锁,由JVM通过monitorenter和两个monitorexit指令保障,覆盖所有异常类型,且保证内存可见性;而ReentrantLock需手动unlock,易因遗漏导致锁泄漏。

synchronized 在异常发生时会自动释放锁,不需要任何额外处理,这是它最稳定、最省心的特性之一。
底层靠字节码指令保障
JVM 在编译 synchronized 代码块时,会插入 monitorenter 和 两个 monitorexit 指令:一个用于正常执行结束,另一个专用于所有可能的异常出口。无论抛出的是 RuntimeException、Error(比如 OutOfMemoryError),还是线程被中断,JVM 都会通过异常表机制跳转到对应的 monitorexit,确保锁一定释放。
各种异常场景都适用
- 未捕获的 NullPointerException 或 ArrayIndexOutOfBoundsException:锁立刻释放
- 手动 throw new RuntimeException():进入异常路径,触发 monitorexit
- 调用 Thread.interrupt() 后抛出 InterruptedException:锁照常释放
- 发生致命错误如 StackOverflowError 或 OutOfMemoryError:JVM 仍执行锁清理
和 Lock 的关键区别
ReentrantLock 必须在 finally 块中显式调用 unlock(),漏写或异常发生在 unlock 前,就会导致锁泄漏;而 synchronized 完全由 JVM 管理,不依赖开发者编码习惯,从根本上杜绝了这类风险。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
释放时仍保证内存可见性
即使中途抛异常,只要变量修改发生在锁释放前,JVM 就会在 monitorexit 时把工作内存中的变更刷新回主内存。下一个拿到该锁的线程,也会清空本地缓存、重新读取最新值——异常不影响同步带来的可见性语义。
立即学习“Java免费学习笔记(深入)”;

















