使用CompletionService结合ExecutorService批处理任务

Posted 张宇航

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用CompletionService结合ExecutorService批处理任务相关的知识,希望对你有一定的参考价值。

CompletionService用于提交一组Callable任务,其take方法返回已完成的一个Callable任务对应的Future对象。
如果你向Executor提交了一个批处理任务,并且希望在它们完成后获得结果。为此你可以将每个任务的Future保存进一个集合,然后循环这个集合调用Future的get()取出数据。幸运的是CompletionService帮你做了这件事情。
CompletionService整合了Executor和BlockingQueue的功能。你可以将Callable任务提交给它去执行,然后使用类似于队列中的take和poll方法,在结果完整可用时获得这个结果,像一个打包的Future。
CompletionService的take返回的future是哪个先完成就先返回哪一个,而不是根据提交顺序。
例子:
技术分享
 1 import java.util.Random;
 2 import java.util.concurrent.Callable;
 3 import java.util.concurrent.CompletionService;
 4 import java.util.concurrent.ExecutionException;
 5 import java.util.concurrent.ExecutorCompletionService;
 6 import java.util.concurrent.ExecutorService;
 7 import java.util.concurrent.Executors;
 8  
 9 public class CallableAndFuture {
10  
11         public static void main(String[] args) {
12               ExecutorService threadPool = Executors. newFixedThreadPool(10);
13               CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(threadPool);
14  
15                for (int i = 0; i < 10; i++) {
16                       final int seq = i;
17                      System. out.println("开始提交第" + seq + "个任务");
18                      completionService.submit( new Callable<Integer>() {
19  
20                             @Override
21                             public Integer call() throws Exception {
22                                   Thread. sleep(new Random().nextInt(5000));
23                                    return seq;
24                            }
25                      });
26               }
27  
28                for (int i = 0; i < 10; i++) {
29                       try {
30                             // 取出并移除表示下一个已完成任务的 Future,如果目前不存在这样的任务,则等待。
31                            Integer seq = completionService.take().get();
32                            System. out.println("第" + seq + "个任务返回");
33                      } catch (InterruptedException e) {
34                            e.printStackTrace();
35                      } catch (ExecutionException e) {
36                            e.printStackTrace();
37                      }
38               }
39        }
40  
41 }
技术分享

 

以上是关于使用CompletionService结合ExecutorService批处理任务的主要内容,如果未能解决你的问题,请参考以下文章

Java技术指南「并发编程专题」CompletionService框架基本使用和原理探究(基础篇

Java线程之CompletionService

Java深层系列「并发编程系列」让我们一起探索一下CompletionService的技术原理和使用指南

completionService

通俗易懂的JUC源码剖析-CompletionService

深入浅出Java并发编程指南「难点 - 核心 - 遗漏」让我们一起探索一下CompletionService的技术原理和使用指南