java - 除非使用 Thread.interrupted(),否则会错过中断吗?

标签 java multithreading

我对 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/

相关文章:

java - Java 接口(interface)中的静态方法

java - Netty 客户端只能与 Netty 服务器一起使用吗?

java - 套接字编程 - Java 服务器,C(或其他)客户端 - 服务器给出 "invalid stream header"

java - Spring Boot - application.yml,从文件中读取值

java - 顶点 : resource allocation when verticles are idle?

python - 可停止线程错误

java - 在 Java 解释中增加一个字符

c# - Windows线程池和CLR线程池有什么区别

java - 如何知道线程需要完成的确切时间

android - 计时器异常 - java.lang.RuntimeException : Can't create handler inside thread that has not called Looper. prepare() - Android