The only model that I can come up with for running multiple similar processes (SIMD) using
Java Futures (java.util.concurrent.Future<T>
) is as follows:
class Job extends Callable<T> {
public T call() {
// ...
}
}
List<Job> jobs = // ...
List<Future<T>> futures = ExecutorService.invokeAll(jobs);
for (Future<T> future : futures) {
T t = future.get();
// Do something with t ...
}
The problem with this model is that if job 0 takes a long time to complete, but jobs 1, 2, and 3 have already completed, the for
loop will wait to get the return val开发者_高级运维ue from job 0.
Is there any model that allows me to get each Future
result as it becomes available without just calling Future.isDone()
and busy waiting (or calling Thread.sleep()
) if none are ready yet?
You can try out the ExecutorCompletionService
:
http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorCompletionService.html
You would simply submit your tasks and call take until you've received all Futures.
Consider using ListenableFuture
from Guava. They let you basically add a continuation to execute when the future has completed.
Why don't you add what you want done to the job?
class Job extends Runnable {
public void run() {
// ...
T result = ....
// do something with the result.
}
}
That way it will process the result as soon as it is available, concurrently. ;)
A CompletionService
can be polled for available results.
If all you want is the results as they become available however, we wrote an AsyncCompleter
that abstracts away the detail of completion service usage. It lets you submit an Iterable<Callable<T>>
of jobs and returns an Iterable<T>
of results that blocks on next()
and returns the results in completion order.
精彩评论