我知道这是一个老问题,但我认为上面的答案实际上不太正确。 (除了@Skylion,它并没有真正解决问题......):)
Thread.interrupt()本身不会抛出任何异常。它做了两件事:首先,它只是设置一个内部被打断-flag 然后检查是否被调用的线程目前正在阻止类似的活动wait(), sleep(), or join()。如果它找到一个,那么它会唤醒该方法并导致那个方法在调用它的线程内抛出异常on(不是来自)。
在你打电话的情况下interrupt()
从线程本身来看,该线程显然本身当前不能阻塞这些调用之一,因为它当前正在执行您的interrupt()
称呼。所以,只有内部被打断-flag 已设置,并且根本不会引发任何异常。
下次您调用其中一种阻塞方法时(例如sleep()
在 @OldCurmudgeon 的例子中)来自该线程,that方法会注意到被打断- 标记并抛出InterruptedException.
如果您从未调用任何这些方法,您的线程将继续运行,直到它以其他方式终止,并且永远不会抛出异常InterruptedException
。即使您打电话也是如此interrupt()
来自不同的线程。
因此,要注意到您的线程已被中断,您要么需要经常使用抛出异常的阻塞方法之一InterruptedException
然后当您收到这些异常之一时退出,或者您需要经常调用Thread.interrupted()检查内部被打断-标记自己,如果它再次出现就退出true
。但您也可以简单地忽略异常和结果Thread.interrupted()
完全并保持线程运行。所以,interrupt()
命名可能有点含糊。它根本不必“中断”(如“终止”)线程,它只是向线程发送一个信号,线程可以根据需要处理或忽略该信号。很像 CPU 上的硬件中断信号(这可能就是这个名字的由来)。
让异常被抛出join()
主线程中的方法,您需要调用interrupt()
on that线程,而不是在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)
}
}