java中Executor和ExecutorCompletionservice之间的区别

Dip*_*pta 15 java multithreading java.util.concurrent

问题标题本身说明了java中Executors和ExecutorCompletionService类之间的区别是什么?

我是Threading的新手,所以如果有人可以用一段代码来解释,那将会有很大帮助.

Tim*_*der 20

假设您有一组任务,A, B, C, D, E并且您希望在一个任务中异步执行它们,并在Executor完成时逐个处理结果.

有了Executor,你会这样做:

List<Future<?>> futures = new ArrayList<Future<?>>();
futures.add(executorService.submit(A));
futures.add(executorService.submit(B));
futures.add(executorService.submit(C));
futures.add(executorService.submit(D));
futures.add(executorService.submit(E));

//This loop must process the tasks in the order they were submitted: A, B, C, D, E
for (Future<?> future:futures) {
    ? result = future.get();
    // Some processing here
}
Run Code Online (Sandbox Code Playgroud)

此方法的问题在于无法保证任务A首先完成.因此,当主线程A可以处理另一个任务(比如任务B)的结果时,主线程可能会空闲地等待任务完成.使用a可以减少结果处理延迟ExecutorCompletionService.

List<Future<?>> futures = new ArrayList<Future<?>>();
futures.add(executorCompletionService.submit(A));
futures.add(executorCompletionService.submit(B));
futures.add(executorCompletionService.submit(C));
futures.add(executorCompletionService.submit(D));
futures.add(executorCompletionService.submit(E));

//This for loop will process the tasks in the order they are completed,  
//regardless of submission order
for (int i=0; i<futures.size(); i++) {
    ? result = executorCompletionService.take().get();
    // Some processing here
}
Run Code Online (Sandbox Code Playgroud)

因此,实质上,ExecutorCompletionService当处理任务结果的顺序无关紧要时,可以用来挤出更高的效率.

但要注意一件重要的事情.ExecutorCompletionService的实现包含结果队列.如果take或未poll调用以排空该队列,则会发生内存泄漏.有些人使用Futurereturn by submit来处理结果,这不是正确的用法.