Java Reference
In-Depth Information
6.3.5.
CompletionService
: Executor Meets
BlockingQueue
If you have a batch of computations to submit to an
Executor
and you want to retrieve their
results as they become available, you could retain the
Future
associated with each task and
repeatedly poll for completion by calling
get
with a timeout of zero. This is possible, but
tedious. Fortunately there is a better way: a
completion service
.
CompletionService
combines the functionality of an
Executor
and a
Blockin-
gQueue
. You can submit
Callable
tasks to it for execution and use the queuelike methods
take
and
poll
to retrieve completed results, packaged as
Future
s, as they become avail-
able.
ExecutorCompletionService
implements
CompletionService
, delegating
the computation to an
Executor
.
The implementation of
ExecutorCompletionService
is quite straightforward. The
constructor creates a
BlockingQueue
to hold the completed results.
Future-Task
has
a
done
method that is called when the computation completes. When a task is submitted, it
is wrapped with a
QueueingFuture
, a subclass of
FutureTask
that overrides
done
to
methods delegate to the
BlockingQueue
, blocking if results are not yet available.
Listing 6.14.
QueueingFuture
Class Used By
ExecutorCompletionService
.
6.3.6. Example: Page Renderer with
CompletionService
We can use a
CompletionService
to improve the performance of the page renderer in
two ways: shorter total runtime and improved responsiveness. We can create a separate task
for downloading
each
image and execute them in a thread pool, turning the sequential down-
load into a parallel one: this reduces the amount of time to download all the images. And by