今天在看java线程同步之类的东西,忽然想到,如果java同步代码块中的代码抛出了异常,那么该线程是否会释放锁资源呢?于是,我写了代码测试了一下:
package com;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TestTryLock {
private int j = 0;
private Lock lock = new ReentrantLock();
public static void main(String[] args) {
TestTryLock tt = new TestTryLock();
for (int i = 0; i < 2; i++) {
new Thread(tt.new Adder()).start();
new Thread(tt.new Subtractor()).start();
}
}
private class Subtractor implements Runnable {
public void run() {
try {
Thread.sleep(1000); //这样可以保证每次启动Adder和Subtractor两个线程的时候,肯定是Adder先获得锁
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (true) {
synchronized (TestTryLock.this) {
System.out.println("j-- =" + j--);
}
}
}
}
private class Adder implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
synchronized (TestTryLock.this) {
System.out.println("j++ =" + j++);
try {
throw new Exception("hello , world,in Adder");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
try {
Thread.sleep(100); // *在假设抛出异常之后锁会被释放,那么我在捕获异常的时候人为地让程序睡眠100ms,以便给Subtractor足够的机会获得被Adder释放的锁
} catch (InterruptedException i) {
// TODO Auto-generated catch block
i.printStackTrace();
}
}
}
}
}
}
}
类TestTryLock分别有两个内部类Adder和Subtractor,我试着让Adder线程先执行(我刻意地在Adder类的run方法里加了sleep,代码1,这样可以保证每次启动Adder和Subtractor两个线程的时候,肯定是Adder先获得锁)并在while循环中持续获得锁,然后,在同步块里面,抛出Exception异常,注意,是Exception而不是RuntimeException.不了解RuntimeException和Exception的同学可以先去看看相关的文章,总之Exception异常是需要强制捕获的,而且捕获只有代码正常往下执行,不会中断。另外,在假设抛出异常之后锁会被释放,那么我在捕获异常的时候人为地让程序睡眠100ms,以便给Subtractor足够的机会获得锁。
j++ =0
java.lang.Exception: hello , world,in Adder
at com.TestTryLock$Adder.run(TestTryLock.java:61)
at java.lang.Thread.run(Unknown Source)
j++ =1
java.lang.Exception: hello , world,in Adder
at com.TestTryLock$Adder.run(TestTryLock.java:61)
at java.lang.Thread.run(Unknown Source)
j++ =2
java.lang.Exception: hello , world,in Adder
at com.TestTryLock$Adder.run(TestTryLock.java:61)
at java.lang.Thread.run(Unknown Source)
可以很清楚的看到,即使发生了Exception,并且在Exception发生之后我让Adder睡眠最够的时间,Subtractor也无法获得锁,这说明,异常发生了以后,该线程根本没有释放锁,也就是说,同步快中的Exception,不会影响锁的释放。