我对 Java 教程中的以下示例有疑问:https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
for (int i = 0; i < importantInfo.length; i++) {
// Pause for 4 seconds
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
// We've been interrupted: no more messages.
return;
}
// Print a message
System.out.println(importantInfo[i]);
}
Java 教程似乎表明这可以很好地处理异常,因为大部分执行时间将花费在 Thread.sleep() 上,如果线程收到中断,它会抛出 InterruptedException。
但是,如果代码在执行 println
时接收到中断,那么这个示例难道不会完全错过中断吗?因此,像下面这样修改它(添加另一个对 Thread.interrupted() 的调用)不是最安全的吗?
for (int i = 0; i < importantInfo.length; i++) {
// Pause for 4 seconds
try {
if (Thread.interrupted()){
throw new InterruptedException()
}
Thread.sleep(4000);
} catch (InterruptedException e) {
// We've been interrupted: no more messages.
return;
}
// Print a message
System.out.println(importantInfo[i]);
}
但实际上,如果是这种情况,我们永远不能依赖 InterruptedException 来提供帮助,除非我们可以接受它有时会丢失,或者如果我们在循环或其他情况下中断线程。我错过了什么?
最佳答案
没有。中断线程会设置一个标志,下次检查该标志Thread.sleep(...)
被调用。
所以,即使它不在 Thread.sleep
中当中断发生时,中断不会丢失。
要做的一件重要的事情是在捕获 InterruptedException
时重新中断线程。 :
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
// ...
}
这使得该方法之外的代码知道该方法提前完成的原因是因为中断;它也应该处理中断。如果run()
这可能并不重要方法由 Thread
直接执行;但这并不是运行该方法的唯一方式。
顺便说一句,编写该代码的一种更简洁的方法是捕获循环外的中断:
try {
for (int i = 0; i < importantInfo.length; i++) {
// Pause for 4 seconds
Thread.sleep(4000);
// Print a message
System.out.println(importantInfo[i]);
}
} catch (InterruptedException e) {
// We've been interrupted: no more messages.
Thread.currentThread().interrupt();
}
我发现在外面做会更清楚,因为它清楚地表明中断会停止循环迭代。
关于java - 除非使用 Thread.interrupted(),否则会错过中断吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49499894/