在处理取消时的线程中,您经常会看到像这样的代码
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。
答案 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
}