简体   繁体   English

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

[英]Java Threads: Shutdown flag vs Catching Exception

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. 我看到它的方式是,在后一种情况下,你根本不需要打扰关闭var。

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

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. 这是一篇关于同一点的好文章,它也指出了线程中断的一些I / O注意事项。 http://www.javaspecialists.eu/archive/Issue056.html http://www.javaspecialists.eu/archive/Issue056.html

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

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

Also, the flag can be externalized as a read-only property (say, as a getter). 此外,该标志可以外部化为只读属性(例如,作为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. 在个人方面,我不喜欢Java使用InterruptedException,因为它通常不是每个例外的例外,而是信号,通常是正常和预期的信号。 Oh well. 那好吧。

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
}

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

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