繁体   English   中英

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

[英]Java Threads: Shutdown flag vs Catching Exception

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

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。

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

我不建议使用线程中断作为您唯一的关机机制。

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

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

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

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

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

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

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

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
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM