我知道这是一个老问题,但我认为上面的答案实际上并不完全正确。(除了@Skylion's,它并没有真正解决这个问题......):)
Thread.interrupt()
本身不会抛出任何异常。它做了两件事:首先它简单地设置一个内部中断标志,然后它检查它被调用的线程当前是否阻塞了一个活动,如wait()
、sleep()
或join()
。如果它找到一个,那么它会唤醒该方法并导致该方法在调用它的线程内(而不是从)抛出异常。
在您interrupt()
从线程本身调用的情况下,该线程显然当前不能阻塞其中一个调用,因为它当前正在执行您的interrupt()
调用。因此,只设置了内部中断标志,根本不抛出异常。
下次您sleep()
从该线程调用其中一个阻塞方法(如在@OldCurmudgeon 的示例中)时,该方法将注意到中断- 标志并抛出InterruptedException
.
如果您从未调用任何这些方法,您的线程将继续运行,直到它以其他方式终止并且永远不会抛出InterruptedException
. 即使您interrupt()
从不同的线程调用也是如此。
因此,要注意您的线程已被中断,您要么需要经常使用其中一种阻塞方法,InterruptedException
当您收到其中一个异常时抛出一个然后退出,或者您需要经常调用Thread.interrupted()
以检查内部中断- 标志自己如果它返回则退出true
。但是您也可以完全忽略异常和结果Thread.interrupted()
并保持线程运行。所以,interrupt()
名字可能有点含糊。它根本不一定“中断”(如“终止”)线程,它只是向线程发送一个信号,线程可以随意处理或忽略。很像 CPU 上的硬件中断信号(这可能是名称的来源)。
要让主线程中的方法抛出异常join()
,您需要调用该线程,而不是 on interrupt()
,如下所示:MyThread
public static void main(String[] args) {
MyThread t = new MyThread();
t.setDaemon(true); // Quit when main thread is done
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!!!
while (true); // Keep thread running (see comments)
}
}