Java的Thread.sleep啥时候抛出InterruptedException?

Posted

技术标签:

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

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

【问题讨论】:

***.com/questions/1024651/… 取决于您的意思是“忽略”。 InterruptedException 是一个被捕获的异常,所以你不能编译,除非你在任何加入或休眠 Thread 的方法上处理或声明这种类型的异常,或者在 Object 上调用 wait() 【参考方案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();
         
    

来自Don't swallow interrupts

在此处查看整篇论文:

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 方法被退出。

以上是关于Java的Thread.sleep啥时候抛出InterruptedException?的主要内容,如果未能解决你的问题,请参考以下文章

Java两种延时——thread和timer

Thread 类 PowerMockito 模拟 Thread.sleep 抛出中断异常的场景

Thread.sleep 没有抛出 InterruptedException

java中的thread.sleep(1000) 用法

隐藏 Thread.sleep

C# 中的 Thread.Sleep(1) 有啥影响?