我有这样的东西:
ExecutorService executor = Executors.newFixedThreadPool(2);
CompletionService<Boolean> completionService = new ExecutorCompletionService<>(executor);
int i = 0;
while (i < 40) {
completionService.submit(getTask());
i++;
}
executor.shutdown();
System.out.println("SHUTDOWN");
调用shutdown
后,将执行所有提交的任务。如果我调用shutdownNow
,那么当前执行的线程是抛出java.lang.InterruptedException
。
有什么方法可以等待当前执行的任务完成而不执行其他提交的任务?
>shutdown()
允许当前提交的任务完成,但拒绝新任务:
启动有序关闭,在该关闭中执行以前提交的任务,但不接受任何新任务。
如果要在main
线程中等待执行程序关闭,可以调用executor.awaitTermination(long timeout, TimeUnit unit)
:
阻止,直到所有任务在关闭请求后完成执行,或者发生超时,或者当前线程中断,以先发生者为准。
如果要允许当前正在运行的任务完成,但放弃已提交到队列的任务,则有以下几种选择:
-
取消期货与
cancel(false)
:尝试取消此任务的执行。如果任务已完成、已取消或由于其他原因无法取消,则此尝试将失败。如果成功,并且在调用取消时此任务尚未启动,则此任务不应运行。
退货: 如果任务无法取消,则为 false,通常是因为它已经正常完成;否则为真
-
使用自定义
CancellableRunnable/Callable
包装您的Runnable
/Callable
(取决于您getTask()
返回的内容):class CancellableRunnable implements Runnable { private final AtomicBoolean shouldRun; private final Runnable delegate; public CancellableRunnable(AtomicBoolean shouldRun, Runnable delegate) { this.shouldRun = shouldRun; this.delegate = delegate; } @Override public void run() { if (shouldRun.get()) { delegate.run(); } } }
以及示例中的用法:
AtomicBoolean shouldRun = new AtomicBoolean(true); while (i < 40) { completionService.submit(new CancellableRunnable(shouldRun, getTask())); i++; } shouldRun.set(false); executor.shutdown();
是的,在您调用shutdown()
后,执行者将不接受任何新任务。接下来,调用 awaitTermination()
以等待正在运行的任务完成。
如果您只需要前两个结果,然后放弃其他任务,则可以等待前两个任务完成,然后取消其他任务,例如,如果您不再需要完成服务,则调用 shutdownNow。
Future<Boolean> result1 = copmletionService.take();
Future<Boolean> result2 = copmletionService.take();
completionService.shutdownNow();