6

在做一个项目时,我遇到了这个用于生产系统的代码:

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 中公开的永不丢弃异常的基本原则,并以我自己的丰富经验来支持必须调试其他人确实丢弃异常的代码。迄今为止,我还没有找到一个好主意的案例(有时捕获检查的异常并抛出运行时是有争议的,但我在这里不是在谈论这些案例)。

提前感谢您的任何评论。

4

2 回答 2

5

这是一篇关于这个特殊例外的精彩文章:

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

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

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

作者并不关心他的 Thread 的睡眠被中断(这是吞下异常的正当理由);但是,中断可能需要在作者编写代码时不知道或不考虑的线程中的其他地方:

无论您是否打算对中断请求采取行动,您仍然希望重新中断当前线程,因为单个中断请求可能有多个“接收者”。标准的线程池(ThreadPoolExecutor)工作线程实现是响应中断的,因此中断线程池中运行的任务可能会产生取消任务和通知执行线程线程池正在关闭的效果。

于 2013-07-24T11:08:56.560 回答
3

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

IMO,您可以安全忽略 an 的唯一情况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();
于 2013-07-24T11:09:19.790 回答