始终忽略在Java中调用Thread sleep()的InterruptedException是否安全

时间:2013-07-24 11:04:44

标签: java multithreading exception

在处理项目时,我遇到了用于生产系统的代码:

public static void sleepUntil(long millisecondToWake) {
    while (true) {
        long currentMillisecond = System.currentTimeMillis();
        if (currentMillisecond >= millisecondToWake) {
            break;
        }
        try {
            Thread.sleep(millisecondToWake - currentMillisecond);
        }
        catch (InterruptedException ignoredException) {
            // do nothing
        }
    }
}

我一直坚持不断删除Joshua Bloch在Effective Java中暴露的异常的基本原则,并且支持我自己的调试代码,而其他人确实丢弃了异常。到目前为止,我还没有找到一个好主意的案例(有时候捕获已检查的异常并抛出运行时是合理的,但我不是在谈论这些情况)。

提前感谢任何评论。

2 个答案:

答案 0 :(得分:4)

以下是关于此特殊例外的精彩文章:

http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html

基本上,它不应该被忽略,至少代码应该做的是传播中断:

catch (InterruptedException e) { 
    // Restore the interrupted status
    Thread.currentThread().interrupt();
}

作者并不关心他的线程的睡眠是否被中断(这是吞下异常的正当理由);然而,作者在编写代码时不知道或想到的线程中可能需要中断:

  

您是否计划对中断请求采取行动,您仍然希望重新中断当前线程,因为单个中断请求可能有多个“收件人”。标准线程池(ThreadPoolExecutor)工作线程实现响应中断,因此中断线程池中运行的任务可能会同时取消任务并通知执行线程线程池正在关闭。

答案 1 :(得分:3)

在该具体示例中,这似乎不是一种合理的方法。特别是,如果用户想要退出程序(例如),JVM将一直挂起,直到你的睡眠方法结束,这似乎是不合理的。

IMO,唯一可以安全忽略InterruptedException的情况是:

  • 您可以完全控制执行方法的线程,
  • 在忽略异常后立即退出。

在任何其他情况下,您应该:重置中断的标志并立即退出。

例如,这样就可以了:

//the task is local, nobody else can access it
final Runnable localRunnable = new Runnable() {
    public void run() {
        //catch, ignore and exit immediately
        try { Thread.sleep(10000); } catch (InterruptedException e) {}
    }
}
//it is your own thread and you have full control over it
new Thread(localRunnable).start();