如果我按如下方式编写代码,则无法中断或终止线程。同样,它不会抛出InterruptedException。
Thread loop = new Thread(
new Runnable() {
@Override
public void run() {
while (true) {
}
}
}
);
loop.start();
loop.interrupt();
要中断此线程,我需要修改我的代码,如下所示:
Thread loop = new Thread(
new Runnable() {
@Override
public void run() {
while (true) {
if (Thread.interrupted()) {
break;
}
// Continue to do nothing
}
}
}
);
loop.start();
loop.interrupt();
我的问题是
我已经阅读了许多有关InterruptedException的博客和文章,但是没有找到任何令人信服的答案。
编辑
在InterruptedException上找到了不错的文章:
http://codepumpkin.com/interruptedexception-java-multithreading/
最佳答案
thread.interrupt()
的全部要点是它是协作的。线程被中断,但是它必须使用Thread.currentThread().isInterrupted()
检查中断标志,以便它可以正确管理其自身的终止,并在必要时清理共享对象,锁,最终块等。
引用tutorial on the subject,重点是我的。
确实会引发InterruptedException
的方法是在锁和其他条件下等待的方法。它们在被中断时会引发异常,因此线程可以在终止之前自行进行清理。
另一种选择是让InterruptedException
是一个RuntimeException
,无论程序是否预期它,都可以随时抛出它。 stop()
和其他不推荐使用的Thread
方法的部分问题是,它们倾向于违反各种语言结构,并可能离开
应用程序内存处于错误状态。这是more details about that。
如果是InterruptedException
,那么对于RuntimeException
也可以这样说。您可以想象,如果线程正在更改共享对象,然后只是中途抛出了意外的RuntimeException
或被完全停止了。被更新的共享库很容易处于无效状态。
这不是正确的调用方法,因为它清除了线程上的中断标志,这是一个错误的模式。请使用以下内容:
这将保留中断标志,如果可能的话,应执行此操作。同样,当InterruptedException
抛出时,也会清除中断标志。这就是为什么这样做是一个很好的模式:
try {
...
} catch (InterruptedException ie) {
// re-interrupt the thread to propagate the interrupt flag
Thread.currentThread().interrupt();
// handle the interrupt here by probably quitting the thread
}
库“吞噬”中断标志存在许多问题。即使您的代码很小,也可能将其复制到一个较大的块中,因此您始终可以将中断标志恢复为一个好的模式。