Java 线程:关闭标志与捕获异常
在线程中处理取消时,您经常会看到这样的代码
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
}
我看到的方式是,在后一种情况下,您不需要完全不用担心 shutdown var。
In threads when dealing with cancelation, you often you see code like this
while (!shutdown) {
.. do something, if a blocking call, then it will throw the interrupted exception
try { .. some more ... }
catch (InterruptedException e) {
shutdown = true;
}
}
What I want to know is, is this, or why is this, better than doing this
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
}
The way I see it is that in the latter case you don't need to bother with the shutdown var at all.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在第一个版本中,您可以与调用代码共享关闭标志(或类似的关闭机制),允许它仅通过设置标志来尝试完全正常关闭,而无需中断线程 - 如果正常关闭,则可能会回落到中断关机失败。
我不建议使用线程中断作为您唯一的关闭机制。
(当然,同样要小心如何处理共享标志。您需要使其成为线程安全的;在简单情况下,一个 volatile 变量可能就足够了。)
In the first version, you can share the shutdown flag (or a similar shutdown mechanism) with the calling code, allowing it to attempt a completely graceful shutdown just by setting the flag, without interrupting the thread - possibly falling back to interruption if the graceful shutdown fails.
I wouldn't suggest using thread interruption as your only shutdown mechanism.
(Equally, be careful with how you handle the shared flag, of course. You'll need to make it thread-safe; a volatile variable would probably be enough in simple cases.)
您不使用异常作为退出某种情况的方式(至少通常不会,这是最好避免的做法。)异常是为了...提示鼓...宣布异常,错误,情况和通常或潜在的恶劣条件。
关闭(通常)不是错误条件,因此至少从哲学/设计的角度来看,我更喜欢使用关闭标志变量的第一个选项。
此外,该标志可以外部化为只读属性(例如,作为 getter)。然后线程外部的组件可以查看线程是否仍然处于活动状态(如果它们具有合法依赖于该线程的逻辑)。
就我个人而言,我不喜欢 Java 使用 InterruptedException,因为它通常不是一个异常,而是一个信号,通常是正常的预期信号。那好吧。
You don't use exceptions as a way to exit from a condition (at least not typically, and it is a practice best to be avoided.) An exception is for ... cue drums ... announce exceptions, errors, situations and conditions that are typically or potentially bad.
A shutdown is not (typically) an error condition, so at least from that philosophical/design point of view, I would prefer the first option using the shutdown flag variable.
Also, the flag can be externalized as a read-only property (say, as a getter). Then components external to the thread can see whether the thread is still active (if they have logic that legitimately depends on that.)
On a personal note, I dislike that Java uses InterruptedException as it is typically not an exception per say, but a signal, typically a normal and expected signal. Oh well.
我认为第二种方式更干净。这是一篇关于同一点的好文章,其中还指出了一些有关线程中断的 I/O 注意事项。
http://www.javaspecialists.eu/archive/Issue056.html
I think the second way is cleaner. Here's a good article on the same point which also points out some I/O considerations around thread interruption.
http://www.javaspecialists.eu/archive/Issue056.html
我建议您使用finally来清理线程(因为这总是被调用),而不是仅仅为了打破循环而抛出异常。尝试
I would suggest you use finally to cleanup a thread (as this is always called) and not to throw an exception just to break a loop. try