今天看了一下抛出异常时锁是否会被释放的问题,我们先来看说明问题的程序
public class Main {
class ThreadObj extends Thread{
@Override
public void run() {
try {
testSynMethod();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
String lockObj = "lockMe";
void testSynMethod() throws InterruptedException{
synchronized(lockObj){
System.out.println(Thread.currentThread().getName());
//确保两个另一线程也进入了此方法
Thread.currentThread().sleep(2000);
throw new RuntimeException("i am an Exception");
}
}
public static void main(String[] args) {
Main m = new Main();
Main.ThreadObj t1 = m.new ThreadObj();
t1.setName("thread1");
Main.ThreadObj t2 = m.new ThreadObj();
t2.setName("thread2");
t1.start();
t2.start();
}
}
代码很简单,启动了两个线程执行同一个方法, 让线程在获取对象锁之后抛出异常,看另一个线程是否能获取到对象的锁来执行同步代码块,程序打印的结果如下
thread1
thread2
Exception in thread "thread1" java.lang.RuntimeException: i am an Exception
at com.pay.o2o.test.Main.testSynMethod(Main.java:22)
at com.pay.o2o.test.Main$ThreadObj.run(Main.java:10)
Exception in thread "thread2" java.lang.RuntimeException: i am an Exception
at com.pay.o2o.test.Main.testSynMethod(Main.java:22)
at com.pay.o2o.test.Main$ThreadObj.run(Main.java:10)
从程序执行结果可以看到两个线程都执行了同步操作,也就是说明在同步块中抛出异常,线程是会将同步锁释放的,而且我们还能了解到,释放的速度是很快的,因为第二个线程在第一个线程打印抛出的异常信息之前就执行了打印线程名称的代码。