java中Executor和ExecutorCompletionservice之间的区别

时间:2011-10-13 17:30:43

标签: java multithreading java.util.concurrent

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

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

2 个答案:

答案 0 :(得分: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
}

此方法的问题在于无法保证任务A将首先完成。因此,当主线程可能正在处理另一个任务的结果(比如任务A)时,主线程可能会阻塞等待任务B完成。使用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
}

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

但有一点需要注意。 ExecutorCompletionService的实现包含结果队列。如果未调用takepoll来排空该队列,则会发生内存泄漏。有些人使用Future返回的submit来处理结果,这是不正确的用法。

答案 1 :(得分:3)

ExecutorCompletionService将简单地换行并委托给普通的Executor,并提供方便的方法来检索最近完成的任务。

api有一些例子可以让你去

http://download.oracle.com/javase/1,5.0/docs/api/java/util/concurrent/ExecutorCompletionService.html