首页 > 解决方案 > Thread.Interrupt() 不起作用,我真的不明白为什么

问题描述

就像我很沮丧,因为我不明白为什么它不起作用。

这是我的代码的一部分:

if (!loadThread.isInterrupted()) {
    try {
        Thread.sleep(500);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

它给了我错误:

W/System.err: java.lang.InterruptedException
W/System.err:     at java.lang.Thread.sleep(Native Method)
    at java.lang.Thread.sleep(Thread.java:442)
    java.lang.Thread.sleep(Thread.java:358)
    at me.igor.comunicator.client.MainActivity$2.run(MainActivity.java:94)

第 94 行是Thread.sleep(500);。这很奇怪,因为如果它给我的错误是线程被中断,那么为什么会if(!loadThread.isInterrupted()) {被执行为真呢?

标签: javamultithreadingjava-threads

解决方案


您似乎不了解中断的作用或工作原理。

一个简短的教程:

  • 检查其他线程的中断标志的状态是非常奇怪的。您可能想要Thread.interrupted()而不是loadThread.isInterrupted().
  • 当您在线程上设置中断标志时,不会立即发生任何事情。我们不会等待读取标志的东西在该线程中运行,此时会发生一些事情。与该标志只有 2 次交互:
    1. 正在打电话Thread.interrupted。如果在引发线程的中断标志时调用该方法,则将返回true并降低标志
    2. 正在调用与该标志具有特定交互的任何方法。指定给 的每个throws InterruptedException方法,例如Thread.sleep,都保证与之交互:这些方法将抛出InterruptedException 并降低标志。如果在您调用该方法时标志处于上升状态,它们会通过降低标志并抛出异常来立即返回。未指定抛出 InterruptedEx,但会“休眠”的方法,例如fileInputStream.read(),可能会或可能不会与其交互:JVM 的选择。取决于您的操作系统。如果他们与之交互,他们会降下旗帜并抛出 eg IOException。他们不会(也不能) throw InterruptedException

这对您的代码意味着一些事情:

  1. 当然,您的isInterrupted()调用返回 false:它没有中断YET,这发生在这 500 毫秒内。
  2. 一般来说,您根本不需要检查。此处处理中断的唯一方法是捕获该异常。根本没有别的办法。这也将处理所有可能发生的情况,您不需要任何检查。这是您必须编写的代码,它涵盖了所有相关情况:
boolean wasInterrupted;
try {
    Thread.sleep(500);
    wasInterrupted = false;
} catch (InterruptedException e) {
    wasInterrupted = true;
}

if (wasInterrupted) {
   // do whatever you intended to do here
}

你根本不需要打电话的原因Thread.interrupted是因为Thread.sleep它将免费为你做这件事(性能或其他)。

请注意,线程永远不会被任何事情打断,除非您专门编写someThread.interupt()。例如,用户按下 CTRL+C 或进入他们的任务管理器或活动监视器或诸如此类的东西并结束您的进程,无论是否强行,都不会导致中断。


推荐阅读