ExecutorService 中的 InterruptedException

7

当在由ExecutorService管理的任务中捕获InterruptedException时,我们是否应该设置中断标志?还是应该直接忽略InterruptedException

示例:

final ExecutorService service = ...;
final Object          object  = ...;

service.submit(() -> {
    try {
        while (!condition) {
            object.wait();
        }
    } catch (final InterruptedException exception) {
        Thread.currentThread().interrupt(); // yes or no?
    }
});

5
这取决于上下文和要求。一般来说,除非你明确知道自己在做什么并有充分的理由,否则不要随意接受。 - Ole V.V.
2
ExecutorService 中,吞掉异常和不吞掉异常有什么区别?在这两种情况下,ExecutorService 的行为如何? - user4460845
2个回答

4
在提交给ExecutorService的任务中,接收到中断信号意味着取消任务执行。因此,在您的代码示例中,答案是“不”,不要再次设置中断。
据我所见,在源代码中重新断言中断状态将被忽略,但它确实会浪费执行器中的一些工作,因为如果工作线程尝试获取另一个任务,则会立即引发InterruptedException,然后根据执行器的状态确定其为虚假并进行清除。
及时关闭执行器取决于任务响应中断退出;它不依赖于任务恢复中断状态。

请注意,InterruptedException 不仅会在执行器被要求 .shutdown() 时发生。如果相应的 Future<?> 被要求取消,则也会发生此情况。那么 ExecutorService 在这两种情况下是否也会表现相同(忽略或不忽略)? - user4460845
@JasarTolio 是的,它的行为相同。我在我的回答中主要谈到了Future.cancel()调用;突然关闭可以被视为请求对提交的任何任务进行cancel()。对于ThreadPoolExecutor中的工作线程,中断的唯一影响是使其醒来并检查执行器的状态。如果该状态实际上没有改变,它将返回到从工作队列中poll()take()下一个任务。 - erickson
明确的答案!谢谢! - user4460845

0
正如这篇文章所建议的那样,永远不要吞下InterruptedException。

2
这篇文章相当古老,没有考虑到现代Java Concurrent包。当然,这些想法是一样的,但是上下文可能会有所不同,因为ExecutorService负责管理。 - user4460845

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接