Java线程:关闭标志与捕获异常

时间:2011-04-01 12:03:06

标签: java multithreading request-cancelling

在处理取消时的线程中,您经常会看到像这样的代码

while (!shutdown) {
  .. do something, if a blocking call, then it will throw the interrupted exception
  try { .. some more ... } 
  catch (InterruptedException e) { 
    shutdown = true; 
  }
}

我想知道的是,这是为什么,或为什么这样做,比这更好

try {
  while (true) {
    .. do something, if a blocking call, then it will throw the interrupted exception
    if (Thread.interrupted()) throw new InterruptedException();
  }
} catch (InterruptedException e) {
  .. clean up, let thread end
}

我看到的方式是,在后一种情况下,你根本不需要打扰关闭var。

4 个答案:

答案 0 :(得分:7)

在第一个版本中,您可以使用调用代码共享关闭标志(或类似的关闭机制),允许它仅通过设置标志来尝试完全正常关闭,而不会中断线程 - 可能会回退到中断如果正常关机失败。

我不建议使用线程中断作为 only 关闭机制。

(同样,当然要小心你如何处理共享标志。你需要使它成为线程安全的;在简单的情况下,一个volatile变量可能就足够了。)

答案 1 :(得分:2)

我认为第二种方式更清洁。这是一篇关于同一点的好文章,它也指出了线程中断的一些I / O注意事项。 http://www.javaspecialists.eu/archive/Issue056.html

答案 2 :(得分:2)

您不使用异常作为退出条件的方法(至少不是典型的,并且这是一种最好避免的做法。)例外是... cue鼓...宣布例外,错误,通常或可能不好的情况和条件。

关闭不是(通常)错误条件,所以至少从哲学/设计的角度来看,我更喜欢使用shutdown flag变量的第一个选项。

此外,该标志可以外部化为只读属性(例如,作为getter)。然后,线程外部的组件可以查看线程是否仍处于活动状态(如果它们具有合法依赖于该逻辑的逻辑。)

就个人而言,我不喜欢Java使用InterruptedException,因为它通常不是每个例外的例外,而是信号,通常是正常和预期信号。哦,好吧。

答案 3 :(得分:1)

我建议你最后使用来清理一个线程(因为这总是被调用)而不是为了打破一个循环而抛出异常。尝试

try {
  while (!Thread.interrupted()) {
    .. do something, if a blocking call, then it will throw the interrupted exception
  }
} catch (InterruptedException e) {
  // handle exception
} finally {
  .. clean up, let thread end
}