我不明白为什么线程在中断时不会抛出InterruptedException
。
我正在尝试使用以下代码段:
public class InterruptTest {
public static void main(String[] args) { MyThread t = new MyThread(); t.start(); try { t.join(); } catch (InterruptedException ex) { ex.printStackTrace(); } } private static class MyThread extends Thread { @Override public void run() { Thread.currentThread().interrupt(); } } }
在API文档中,它使用interrupt()
方法:
如果在调用Object类的wait(),wait(long)或wait(long,int)方法或Thread.join(),Thread.join(long)的方法中阻止此线程,Thread.join(long,int),Thread.sleep(long)或Thread.sleep(long,int),这个类的方法,然后它的中断状态将被清除,它将收到InterruptedException。
答案 0 :(得分:10)
我知道这是一个老问题,但我认为上面的答案实际上并不完全正确。 (除了@ Skylion,它没有真正解决这个问题......):)
Thread.interrupt()
本身不会抛出任何异常。它做了两件事:首先它只是设置一个内部的被打断的 -flag,然后它检查它被调用的线程当前是否阻塞{{3 },wait()
或sleep()
。如果它找到一个,那么它会唤醒该方法,并导致该方法将异常抛出到 on (而非来自)
如果您从线程本身调用interrupt()
,那么该线程显然当前无法阻止其中一个调用,因为它正在执行您的interrupt()
调用。因此,只设置内部中断的 -flag,并且不会抛出任何异常。
下次你从该线程调用其中一个阻止方法(如@ OldCurmudgeon示例中的sleep()
)时, 方法会注意到被中断 - 标记并抛出join()
。
如果你没有调用任何这些方法,你的线程将继续运行,直到它以其他方式终止,并且永远不会抛出InterruptedException
。即使您从其他线程调用interrupt()
也是如此。
因此,要注意您的线程已被中断,您需要经常使用一种抛出InterruptedException
的阻止方法,然后在收到其中一个异常时退出,或者您需要经常调用InterruptedException
自行检查内部中断的标志,如果它返回 true
则退出。但您也可以完全忽略异常和Thread.interrupted()
的结果并保持线程运行。所以,interrupt()
可能有点含糊不清。它根本不一定“中断”(如“终止”)线程,它只是向线程发送一个信号,线程可以根据需要处理或忽略。就像CPU上的硬件中断信号(可能是名称来源)。
要在主线程中使用join()
方法抛出异常,您需要在那个主题上调用interrupt()
,而不是MyThread
,像这样:
public static void main(String[] args) {
MyThread t = new MyThread();
t.start();
try {
t.join();
} catch (InterruptedException ex) {
System.out.println("Now it works:");
ex.printStackTrace();
}
}
private static class MyThread extends Thread {
private final Thread parentThread;
public MyThread() {
parentThread = Thread.currentThread();
}
@Override
public void run() {
parentThread.interrupt(); // Call on main thread!!!
}
}
答案 1 :(得分:3)
异常总是在自己的线程上抛出。您有两个不同的主题:主线程和您创建的主线程。 MyThread中抛出的异常无法在主要异常中捕获。
答案 2 :(得分:1)
为什么要中断线程?只需使用
return;
答案 3 :(得分:0)
你只是太快了 - 试试这个:
private static class MyThread extends Thread {
@Override
public void run() {
try {
Thread.currentThread().interrupt();
Thread.sleep(5000);
} catch (InterruptedException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, "Oops", ex);
}
}
}
我明白了:
Oct 04, 2013 12:43:46 AM test.Test$MyThread run
SEVERE: Oops
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at test.Test$MyThread.run(Test.java:36)
请注意,您无法将异常传播出run
方法,因为run
不会抛出任何异常。