【问题标题】:When does Java's Thread.sleep throw InterruptedException?Java的Thread.sleep什么时候抛出InterruptedException?
【发布时间】:2010-11-08 10:02:10
【问题描述】:

Java 的 Thread.sleep 什么时候抛出 InterruptedException?忽略它是否安全?我没有做任何多线程。我只想等待几秒钟,然后重试某些操作。

【问题讨论】:

  • 取决于您的意思是“忽略”。 InterruptedException 是一个被捕获的异常,所以你不能编译,除非你在任何加入或休眠 Thread 的方法上处理或声明这种类型的异常,或者在 Object 上调用 wait()

标签: java multithreading sleep interrupted-exception interruption


【解决方案1】:

您通常不应忽略该异常。请看以下论文:

不要吞下中断

有时抛出 InterruptedException 是 不是一个选项,例如当 Runnable 定义的任务调用 可中断的方法。在这种情况下,您无法重新抛出 InterruptedException,但你也不想什么都不做。当一个 阻塞方法检测到中断并抛出 InterruptedException, 它清除中断状态。如果你捕捉到 InterruptedException 但不能重新抛出它,你应该保留证据表明 发生中断,因此调用堆栈上较高的代码可以 了解中断并在需要时做出响应。这个任务 是通过调用 interrupt() 来“重新中断”当前的 线程,如清单 3 所示。至少,每当您捕获 InterruptedException 并且不要重新抛出它,重新中断当前 返回之前的线程。

public class TaskRunner implements Runnable {
    private BlockingQueue<Task> queue;

    public TaskRunner(BlockingQueue<Task> queue) { 
        this.queue = queue; 
    }

    public void run() { 
        try {
             while (true) {
                 Task task = queue.take(10, TimeUnit.SECONDS);
                 task.execute();
             }
         }
         catch (InterruptedException e) { 
             // Restore the interrupted status
             Thread.currentThread().interrupt();
         }
    }
}

在此处查看整篇论文:

http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html?ca=drs-

【讨论】:

    【解决方案2】:

    如果InterruptedException 被抛出,则意味着有东西想要中断(通常是终止)该线程。这是通过调用线程interrupt() 方法触发的。 wait 方法检测到这一点并抛出一个InterruptedException,因此catch 代码可以立即处理终止请求,而不必等到指定的时间结束。

    如果您在单线程应用程序(以及一些多线程应用程序)中使用它,则永远不会触发该异常。我不推荐使用空的 catch 子句来忽略它。 InterruptedException 的抛出清除了线程的中断状态,因此如果处理不当,该信息将丢失。因此我建议运行:

    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
      // code for stopping current task so thread stops
    }
    

    再次设置该状态。之后,完成执行。这将是正确的行为,甚至从未使用过。

    添加这个可能会更好:

    } catch (InterruptedException e) {
      throw new RuntimeException("Unexpected interrupt", e);
    }
    

    ...语句到 catch 块。这基本上意味着它绝不能发生。因此,如果代码在可能发生的环境中重复使用,它会抱怨它。

    【讨论】:

    • Java 中的断言是off by default。所以最好只是抛出一个RuntimeException
    【解决方案3】:

    Java 专家时事通讯(我可以毫无保留地推荐)有一个 interesting article on this,以及如何处理 InterruptedException。非常值得阅读和消化。

    【讨论】:

    • 它说什么?
    【解决方案4】:

    Thread 类的 sleep()wait() 等方法可能会抛出 InterruptedException。如果其他thread 想要中断正在等待或休眠的thread,就会发生这种情况。

    【讨论】:

      【解决方案5】:

      在单线程代码中处理它的一种可靠而简单的方法是在 RuntimeException 中捕获并追溯它,以避免需要为每个方法声明它。

      【讨论】:

        【解决方案6】:

        InterruptedException 通常在睡眠中断时抛出。

        【讨论】:

        • 这是错误的,因为中断的不是睡眠本身,而是运行它的线程。中断是一种线程状态。它只会导致 sleep 方法被退出。
        猜你喜欢
        • 2020-09-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-22
        • 2011-11-10
        • 1970-01-01
        • 2016-09-27
        • 2018-07-26
        相关资源
        最近更新 更多