会释放。在 java 的 synchronized 代码块或方法中,如果执行过程中抛出了未捕获的异常,jvm 会自动释放当前线程持有的对象锁(monitor),允许其他等待该锁的线程继续获取锁并执行。这是 jvm 内置的异常处理机制,确保锁不会因程序错误而永久死锁。

synchronized 代码块中抛出 RuntimeException 的行为
当在 synchronized 块内部发生运行时异常时,锁会被立即释放。以下示例展示了在同步块中抛出 RuntimeException 后,另一个线程如何成功获取锁。

public class SynchronizedExceptionTest {
private final Object lock = new Object();
public void methodA() {
synchronized (lock) {
System.out.println("Thread A: Acquired lock");
throw new RuntimeException("Error in A");
}
}
public void methodB() {
synchronized (lock) {
System.out.println("Thread B: Acquired lock after exception");
}
}
public static void main(String[] args) throws InterruptedException {
SynchronizedExceptionTest test = new SynchronizedExceptionTest();
Thread t1 = new Thread(() -> {
try {
test.methodA();
} catch (Exception e) {
System.out.println("Caught exception in A");
}
});
Thread t2 = new Thread(() -> {
try {
Thread.sleep(100); // Ensure A starts first
test.methodB();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.start();
t2.start();
t1.join();
t2.join();
}
}预期输出:
立即学习“Java免费学习笔记(深入)”;
Thread A: Acquired lock Caught exception in A Thread B: Acquired lock after exception
synchronized 方法中抛出 Error 的行为
即使抛出的是 Error(如 StackOverflowError),只要它未被捕获,锁同样会被释放。以下示例演示了在同步方法中抛出 Error 后的行为。
你是 TypeScript 项目架构专家,专注于脚手架搭建生产就绪的 Node.js 和前端应用。生成包含现代工具链(pnpm、Vite、Next.js)、类型

public class SynchronizedErrorTest {
private final Object lock = new Object();
public synchronized void methodC() {
System.out.println("Thread C: Acquired lock");
throw new Error("Error in C");
}
public synchronized void methodD() {
System.out.println("Thread D: Acquired lock after error");
}
public static void main(String[] args) throws InterruptedException {
SynchronizedErrorTest test = new SynchronizedErrorTest();
Thread t1 = new Thread(() -> {
try {
test.methodC();
} catch (Throwable e) {
System.out.println("Caught throwable in C");
}
});
Thread t2 = new Thread(() -> {
try {
Thread.sleep(100);
test.methodD();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.start();
t2.start();
t1.join();
t2.join();
}
}预期输出:
立即学习“Java免费学习笔记(深入)”;
Thread C: Acquired lock Caught throwable in C Thread D: Acquired lock after error
基于程序中 catch 块内重新抛出异常的具体问题
如果在 synchronized 块中捕获了异常并在 catch 块中重新抛出,锁是否释放?答案是:是的,锁依然会被释放。因为重新抛出的异常最终会离开 synchronized 块,触发 JVM 的锁释放机制。以下示例验证了这一行为。
public class SynchronizedRethrowTest {
private final Object lock = new Object();
public void methodE() {
synchronized (lock) {
System.out.println("Thread E: Acquired lock");
try {
throw new RuntimeException("Original error");
} catch (RuntimeException ex) {
System.out.println("Caught in E, rethrowing");
throw ex; // Rethrow the exception
}
}
}
public void methodF() {
synchronized (lock) {
System.out.println("Thread F: Acquired lock after rethrow");
}
}
public static void main(String[] args) throws InterruptedException {
SynchronizedRethrowTest test = new SynchronizedRethrowTest();
Thread t1 = new Thread(() -> {
try {
test.methodE();
} catch (Exception e) {
System.out.println("Caught exception in main");
}
});
Thread t2 = new Thread(() -> {
try {
Thread.sleep(100);
test.methodF();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.start();
t2.start();
t1.join();
t2.join();
}
}预期输出:
立即学习“Java免费学习笔记(深入)”;
Thread E: Acquired lock Caught in E, rethrowing Caught exception in main Thread F: Acquired lock after rethrow

















