Внеочередные возвраты из Java Futures - PullRequest
12 голосов
/ 04 мая 2011

Единственная модель, которую я могу придумать для запуска нескольких похожих процессов (SIMD) с использованием Java Futures (java.util.concurrent.Future<T>) выглядит следующим образом:

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

Проблема этой модели заключается в том, что если задание 0 занимает много времени, но задания 1, 2 и 3 уже завершены, цикл for будет ожидать получения возвращаемого значения из задания 0.

Есть ли какая-либо модель, которая позволяет мне получать каждый Future результат, когда он становится доступным, без простого вызова Future.isDone() и ожидания ожидания (или вызова Thread.sleep()), если ни одна из них еще не готова?

Ответы [ 4 ]

15 голосов
/ 04 мая 2011

Вы можете попробовать ExecutorCompletionService:

http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorCompletionService.html

Вы просто отправляете свои задания и принимаете колл, пока не получите все фьючерсы.

14 голосов
/ 04 мая 2011

Рассмотрите возможность использования ListenableFuture из Гуава . Они позволяют вам добавить продолжение, которое будет выполнено, когда будущее закончится.

0 голосов
/ 05 мая 2011

A CompletionService можно опросить для получения доступных результатов.

Если вам нужны только результаты по мере их появления, мы написали AsyncCompleter, который абстрагирует детали использования сервиса завершения. Он позволяет вам отправить Iterable<Callable<T>> заданий и возвращает Iterable<T> результатов, которые блокируются на next(), и возвращает результаты в порядке завершения.

0 голосов
/ 04 мая 2011

Почему бы вам не добавить в работу то, что вы хотите сделать?

class Job extends Runnable {
  public void run() {
    // ...
    T result = ....
    // do something with the result.
  }
}

Таким образом, он будет обрабатывать результат, как только он станет доступен, одновременно.;)

...