Executor框架(六)CompletionService 接口

  CompletionService 接口是一个独立的接口,并没有扩展 ExecutorService 。 其默认实现类是ExecutorCompletionService;
  接口 CompletionService 的功能是:以异步的方式一边执行未完成的任务,一边记录、处理已完成任务的结果。从而可以将 任务的执行 与 处理任务的执行结果 分离开来。简单来说,CompletionService 就是监视着 Executor线程池执行的任务,用 BlockingQueue 将完成的任务的结果存储下来。(当然,这个也可以是程序员自己去实现,但是要不断遍历与每个任务关联的 Future,然后不断去轮询,判断任务是否已经完成,比较繁琐);

构造方法摘要

ExecutorCompletionService(Executor executor):
指定一个Executor 来执行任务,存储完成的任务的完成队列是 LinkedBlockingQueue ;
ExecutorCompletionService(Executor executor, BlockingQueue<Future> completionQueue)
指定了任务执行器 Executor 和 已完成的任务队列 completionQueue

方法摘要

Future submit(Callable task):
提交一个 Callable 任务;一旦完成,便可以由take()、poll()方法获取
Future submit(Runnable task, V result):
提交一个 Runnable 任务,并指定计算结果;
Future take() throws InterruptedException
获取并移除表示下一个已完成任务的 Future,如果目前不存在这样的任务,则等待。
Future poll()
获取并移除表示下一个已完成任务的 Future,如果不存在这样的任务,则返回 null。
Future poll(long timeout, TimeUnit unit) throws InterruptedException
获取并移除表示下一个已完成任务的 Future,如果目前不存在这样的任务,则将等待指定的时间(如果有必要)。。

@ Example
  下面的例子是这样一个场景:程序提交了多个任务,但只要有一个任务完成并返回一个非空的结果,并可以忽略掉其余的任务。

 void solve(Executor e, Collection<Callable<Result>> solvers) throws InterruptedException {
     CompletionService<Result> completionService = new ExecutorCompletionService<Result>(e);
     int n = solvers.size();
     List<Future<Result>> futures
         = new ArrayList<Future<Result>>(n);
     Result result = null;
     try {
         //提交多个任务
         for (Callable<Result> s : solvers)
             futures.add(completionService.submit(s));
        //
         for (int i = 0; i < n; ++i) {
             try {
                 //等待获取一个已经完成的任务
                 Result r = completionService.take().get();
                 //判断返回结果是否为空
                 if (r != null) {
                     result = r;
                     break;
                 }
             } catch (ExecutionException ignore) {}
         }
     }
     finally {
         //取消所有任务
         for (Future<Result> f : futures)
             f.cancel(true);
     }

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

原文地址:https://www.cnblogs.com/jinggod/p/8490440.html