Java的Thread.sleep什么时候抛出InterruptedException?

问题描述 投票:0回答:8

Java 的

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

java multithreading sleep interrupted-exception interruption
8个回答
57
投票

您通常不应该忽略异常。看看下面的论文:

不要吞下中断

有时抛出 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-


52
投票

如果抛出

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 块的语句。这基本上意味着它永远不会发生。因此,如果代码在可能发生这种情况的环境中重复使用,它会抱怨它。


13
投票

Java Specialists 时事通讯(我可以毫无保留地推荐)有一篇关于此的有趣的文章,以及如何处理

InterruptedException
。非常值得阅读和消化。


4
投票

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


2
投票

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


1
投票

来自文档

当线程等待时会抛出

InterruptedException
, 睡眠,或以其他方式占用,并且线程被中断,或者 活动前或活动中。

换句话说,当某些代码在特定线程上调用 InterruptedException

 方法时,就会发生 
interrupt()
。这是一个受检查的异常,Java 中的许多阻塞操作都可以抛出它。

中断系统的目的是提供一种替代工作流程,允许线程中断其他线程中的任务。中断不一定会中断正在运行的线程,但它也可以请求线程在下一个方便的机会中断自身。

线程可能因多种原因而被阻塞:

  • 等待从
    Thread.sleep()
  • 中醒来
  • 等待获取锁,等待I/O完成
  • 等待另一个线程中的计算结果等

InterruptedException 通常由所有阻塞方法抛出,以便可以对其进行处理并执行纠正操作。

但是,在大多数情况下,由于我们的代码是 Runnable 的一部分,在这种情况下,我们必须捕获它并恢复状态。

Java 中有很多方法会抛出 InterruptedException。一些例子是:

  • 对象类别:

    • Thread.sleep()
    • Thread.join()
    • wait()
  • 阻塞队列:

    • put()
    • take()

-1
投票

根据个人经验,我只是将

thread.sleep()
更改为
this.sleep()


-7
投票

当睡眠被中断时,通常会抛出

InterruptedException

© www.soinside.com 2019 - 2024. All rights reserved.