As the question title itself says what is the difference between Executors and ExecutorCompletionService classes in java?
I am new to the Threading,so if any one can explain with a piece of code, that would help a lot.
Executor just executes stuff you give it. ExecutorService adds startup, shutdown, and the ability to wait for and look at the status of jobs you've submitted for execution on top of Executor (which it extends).
A CompletionService that uses a supplied Executor to execute tasks. This class arranges that submitted tasks are, upon completion, placed on a queue accessible using take . The class is lightweight enough to be suitable for transient use when processing groups of tasks.
1) The submit() can accept both Runnable and Callable tasks but execute() can only accept the Runnable task. 2) The submit() method is declared in the ExecutorService interface while the execute() method is declared in the Executor interface.
An object that executes submitted Runnable tasks. This interface provides a way of decoupling task submission from the mechanics of how each task will be run, including details of thread use, scheduling, etc. An Executor is normally used instead of explicitly creating threads.
Suppose you had a set of tasks A, B, C, D, E
and you want to execute each of them asynchronously in an Executor
and process the results 1 by 1 as they complete.
With an Executor
, you would do so like this:
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
}
The problem with this method is that there is no guarantee that task A
will complete first. Thus, it is possible that the main thread will be blocking idly waiting for task A
to complete when it could be processing the result of another task (say task B
). Result processing latency could be reduced by using an 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
}
So, in essence, ExecutorCompletionService
could be used to squeeze out a little more efficiency when the order of processing task results does not matter.
One important thing to note though. The implementation of ExecutorCompletionService contains a queue of results. If take
or poll
are not called to drain that queue, a memory leak will occur. Some people use the Future
returned by submit
to process results and this is NOT correct usage.
An ExecutorCompletionService
will simply wrap and delegate to a normal Executor
and offer convenience methods for retrieving the most recently completed tasks.
The api has a few examples that should get you going
http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorCompletionService.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With