Вопрос

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 value 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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top