陷阱 - 捕获 InterruptedException
正如已经在其他陷阱中指出的那样,通过使用捕获所有异常
try {
// Some code
} catch (Exception) {
// Some error handling
}
有很多不同的问题。但是一个特别的问题是它可能导致死锁,因为它在编写多线程应用程序时会破坏中断系统。
如果你开始一个线程,你通常还需要能够出于各种原因突然停止它。
Thread t = new Thread(new Runnable() {
public void run() {
while (true) {
//Do something indefinetely
}
}
}
t.start();
//Do something else
// The thread should be canceld if it is still active.
// A Better way to solve this is with a shared variable that is tested
// regularily by the thread for a clean exit, but for this example we try to
// forcibly interrupt this thread.
if (t.isAlive()) {
t.interrupt();
t.join();
}
//Continue with program
t.interrupt()
将在该线程中引发 InterruptedException,而不是用于关闭线程。但是如果 Thread 需要在完全停止之前清理一些资源呢?为此,它可以捕获 InterruptedException 并进行一些清理。
Thread t = new Thread(new Runnable() {
public void run() {
try {
while (true) {
//Do something indefinetely
}
} catch (InterruptedException ex) {
//Do some quick cleanup
// In this case a simple return would do.
// But if you are not 100% sure that the thread ends after
// catching the InterruptedException you will need to raise another
// one for the layers surrounding this code.
Thread.currentThread().interrupt();
}
}
}
但是如果你的代码中有一个 catch-all 表达式,那么 InterruptedException 也会被它捕获,并且中断将不会继续。在这种情况下会导致死锁,因为父线程无限期地等待这个 thead 用 t.join()
停止。
Thread t = new Thread(new Runnable() {
public void run() {
try {
while (true) {
try {
//Do something indefinetely
}
catch (Exception ex) {
ex.printStackTrace();
}
}
} catch (InterruptedException ex) {
// Dead code as the interrupt exception was already caught in
// the inner try-catch
Thread.currentThread().interrupt();
}
}
}
因此最好单独捕获 Exceptions,但如果你坚持使用 catch-all,至少事先单独捕获 InterruptedException。
Thread t = new Thread(new Runnable() {
public void run() {
try {
while (true) {
try {
//Do something indefinetely
} catch (InterruptedException ex) {
throw ex; //Send it up in the chain
} catch (Exception ex) {
ex.printStackTrace();
}
}
} catch (InterruptedException ex) {
// Some quick cleanup code
Thread.currentThread().interrupt();
}
}
}