一个线程抛出InterruptedException自身是否合适?

3

我正在进行以下工作:

Stopwatch stopWatchToCheckTimeout;

void checkShutDown() throws InterruptedException {
  if (stopWatchToCheckTimeout.elapsed() >= MAX_GRACEFUL_TIMEOUT_DURATION) {
    throw new InterruptedException("Time to shut down now!");
  }
}

public Void mainFancyMethod() {
   try {
     while(true) {
       checkShutDown();
       // do fancy work
     }
   } catch (InterruptedException ex) {
     log.debug("Shutting down gracefully");
   }
   return null;
}

java/lang/InterruptedException文档中,我无法清楚地了解到是否按照标准应该由另一个线程来中断还是一个线程自己抛出此异常。

在这种情况下,最好抛出哪个异常?


1
在Effective Java中,使用异常来控制流程被认为是不好的设计。顺便说一句,我知道这只是一个例子,但是InterruptedException不应该被抑制。否则,在您的情况下抛出此异常将是无意义的。 - Arnaud Claudel
@ArnaudClaudel 它并没有真正被压制,它是跳出了循环,终止了它(但同意,最好设置中断标志或重新抛出异常)。 - user85421
4个回答

4

似乎你在使用异常替代控制流程。你为什么不能只让checkShutDown返回一个布尔值呢?

boolean timedOut() {
  return (stopWatchToCheckTimeout.elapsed() >= MAX_GRACEFUL_TIMEOUT_DURATION)
}

3

一个线程抛出中断异常是正确的,事实上通常情况下线程都是InterruptedException的来源。

在你的情况下,我认为这并不合适,因为它与中断状态无关。你只是想退出执行,这可以通过更为优雅和高效的方式来实现。


1

javax.naming.NamingException的子类?“这是Context和DirContext接口中操作引发的所有异常的超类”? - user85421

0

在您发布的示例中,您不应该抛出InterruptedException

InterruptedException的Javadoc指出:当线程正在等待、睡眠或以其他方式占用时,并且在线程在活动期间或之前被中断时抛出。被中断是由于在运行线程上调用Thread.interrupt(),而这不是您发布的代码中发生的情况。

如果您仍然想使用异常来跳出循环,那么您应该使用其他异常类型。但是,另一种选择是使您的检查方法返回true/false,并将其用于while循环的条件。因此,代替这个:

try {
    while(true) {
        checkShutDown();
        // do fancy work
    }
} catch (InterruptedException ex) {
    log.debug("Shutting down gracefully");
}

做类似这样的事情:

while (checkIfSafeToContinue()) {
    // do fancy work
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接