我有这样的事情:
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
。
有没有办法等待当前执行的任务完成并且不执行其他提交的任务?
答案 0 :(得分:4)
shutdown()
允许当前提交的任务完成,但拒绝新任务:
启动有序关闭,其中执行先前提交的任务,但不接受任何新任务。
如果您想在main
线程中等待执行程序关闭,您可以调用executor.awaitTermination(long timeout, TimeUnit unit)
:
阻止所有任务在关闭请求之后完成执行,或发生超时,或者当前线程被中断,以先发生者为准。
如果要完成当前正在运行的任务,但丢弃已提交到队列的任务,则可以选择以下几种方法:
使用cancel(false)
取消期货:
尝试取消执行此任务。如果任务已完成,已取消或由于某些其他原因无法取消,则此尝试将失败。如果成功,并且在调用cancel时此任务尚未启动,则此任务永远不会运行。
<强>返回强>: 如果任务无法取消,则为false,通常是因为它已经正常完成;否则
使用自定义Runnable
包裹您的Callable
/ CancellableRunnable/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();
答案 1 :(得分:0)
是的,在您致电public static void ProcessHourlyTask([QueueTrigger("hourlytaskqueue")] string message, TextWriter log)
{
//do work
}
public static void ProcessDailyTask([QueueTrigger("daytaskqueue")] string message, TextWriter log)
{
//do work
}
后,执行人将不接受任何新任务。接下来,您调用shutdown()
以等待正在运行的任务完成。
答案 2 :(得分:0)
如果您想要的只是前两个结果然后丢弃其他任务,您可以等待前两个任务完成然后取消其他任务,例如通过调用shutdownNow,如果您不需要完成再服务了。
Future<Boolean> result1 = copmletionService.take();
Future<Boolean> result2 = copmletionService.take();
completionService.shutdownNow();