正如问题标题本身所言,Java中的Executors和ExecutorCompletionService类之间有什么区别?
我是Threading的新手,所以如果有人可以用一段代码进行解释,那将会很有帮助。
最佳答案
假设您有一组任务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
将首先完成。因此,当主线程可能正在处理另一个任务的结果(例如task 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的实现包含一个结果队列。如果未调用
take
或poll
耗尽该队列,则会发生内存泄漏。有些人使用Future
返回的submit
来处理结果,但这不是正确的用法。