javadoc说 invokeAll(Collection<> callables)
扔
interruptedException-如果在等待时中断,在这种情况下,未完成的任务被取消
但是没有关于为什么会中断呼叫的文档。我的程序这样做 - 但很少,我无法编写会导致它发生的测试。
我使用的是一个参数方法而无需超时。
public class ParallelUtil<T> {
public interface Task<T> {
public void execute(T data) throws Exception;
}
public void execute(final Task<T> task, Collection<T> targets) {
ExecutorService executor = null;
try {
executor = Executors.newFixedThreadPool(20);
execute(task, targets, executor);
} finally {
if (executor != null) {
try {
executor.shutdown();
} catch (Exception e) {}
}
}
}
private void execute(final Task<T> task, Collection<T> targets, ExecutorService executor) {
List<Callable<Void>> tasks = new ArrayList<>();
...
try {
executor.invokeAll(tasks);
} catch (Exception e) {
// Here we get InterruptedException - for no reason?
// With some of the tasks left undone!
}
}
}
intruptedException是从 java.util.concurrent.FutureTask.awaitDone(FutureTask.java:400)
可以同时运行的许多ParallelUtils
(从不同的线程启动),但是如您所见,每个呼叫都会创建自己的ExecutorService
,因此它们不应该彼此搞砸。
(作为附带问题,我可以在所有呼叫的情况下使用共享池,而无需互相混乱吗?)
可以同时运行许多此类平行行动(从不同的线程启动)
显然,这些线程中的至少一个直接通过Thread.interrupt()
或间接通过例如Future.cancel(true)
或ExecutorService.shutdownNow()
。
复制此中断的示例:
class Sleep implements ParallelUtil.Task<Integer> {
@Override
public void execute(Integer data) throws Exception {
Thread.sleep(Long.MAX_VALUE);
}
}
class InterruptInvokeAll {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(1);
executorService.submit(
() -> {
ParallelUtil<Integer> parallelUtil = new ParallelUtil<>();
parallelUtil.execute(new Sleep(), Arrays.asList(1));
});
executorService.shutdownNow(); // indirectly interrupts thread that calls executor.invokeAll
}
}
什么会导致
ExecutorService.invokeAll()
投掷InterruptedException
?
请参阅shutdownNow()
的Javadoc:
除了最好的努力试图停止处理主动执行任务之外,没有任何保证。例如,典型的实现将通过
Thread.interrupt()
取消,因此任何未能响应中断的任务都可能永远不会终止。
由于invokeAll
等待直到完成的所有任务,从另一个线程调用shutdownNow()
是invokeAll
调用可以中断的一种方式。
但是,在代码中,您已经向我们显示了它,没有呼叫shutdownNow()
,也没有明显的方法让executor Service对象泄漏到另一个线程。
您的代码(或其他库代码)中的某些内容也可能调用Thread.interrupt
。例如,其中一个任务可能是对自己做。