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

发布于 2024-10-29 05:36:58 字数 603 浏览 1 评论 0原文

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

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

临走之时 2024-11-05 05:36:58

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

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

(当然,同样要小心如何处理共享标志。您需要使其成为线程安全的;在简单情况下,一个 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.)

莫多说 2024-11-05 05:36:58

您不使用异常作为退出某种情况的方式(至少通常不会,这是最好避免的做法。)异常是为了...提示鼓...宣布异常,错误,情况和通常或潜在的恶劣条件。

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

此外,该标志可以外部化为只读属性(例如,作为 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.

姐不稀罕 2024-11-05 05:36:58

我认为第二种方式更干净。这是一篇关于同一点的好文章,其中还指出了一些有关线程中断的 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

冰火雁神 2024-11-05 05:36:58

我建议您使用finally来清理线程(因为这总是被调用),而不是仅仅为了打破循环而抛出异常。尝试

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
}

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

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文