今天是:
带着程序的旅程,每一行代码都是你前进的一步,每个错误都是你成长的机会,最终,你将抵达你的目的地。
title

ExecutorCompletionService

概述

ExecutorCompletionService是一个使用提供的Executor执行任务的CompletionService。该类安排提交的任务在完成后放置在可使用take访问的队列上。该类足够轻量,适用于处理任务组时的瞬态使用。 使用示例。假设你有一组解决某个问题的解算器,每个都返回某类型Result的值,并希望它们并发运行,在某种方法use(Result r)中处理每个返回非空值的结果。你可以这样写:

void solve(Executor e,
            Collection<Callable<Result>> solvers)
     throws InterruptedException, ExecutionException {
   CompletionService<Result> cs
       = new ExecutorCompletionService<>(e);
   solvers.forEach(cs::submit);
   for (int i = solvers.size(); i > 0; i--) {
     Result r = cs.take().get();
     if (r != null)
       use(r);
   }
 }

假设你希望使用任务集合中的第一个非空结果,忽略遇到异常的任何任务,并在第一个任务准备就绪时取消所有其他任务:

void solve(Executor e,
            Collection<Callable<Result>> solvers)
     throws InterruptedException {
   CompletionService<Result> cs
       = new ExecutorCompletionService<>(e);
   int n = solvers.size();
   List<Future<Result>> futures = new ArrayList<>(n);
   Result result = null;
   try {
     solvers.forEach(solver -> futures.add(cs.submit(solver)));
     for (int i = n; i > 0; i--) {
       try {
         Result r = cs.take().get();
         if (r != null) {
           result = r;
           break;
         }
       } catch (ExecutionException ignore) {}
     }
   } finally {
     futures.forEach(future -> future.cancel(true));
   }

   if (result != null)
     use(result);
 }

分享到:

专栏

类型标签

网站访问总量