如何在完成当前执行的任务后关闭CompletionService

时间:2016-03-18 10:14:52

标签: java executorservice java.util.concurrent

我有这样的事情:

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

有没有办法等待当前执行的任务完成并且不执行其他提交的任务?

3 个答案:

答案 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();