Как контролировать заказы, в которых «представляются» Java-фьючерсы? - PullRequest
3 голосов
/ 10 июня 2010

В этом примере я отправляю несколько файлов моему объекту сравнения. Все работает нормально, за исключением того, что я заметил, что порядок, в котором файлы отправляются, не всегда совпадает с порядком их возврата. Любые предложения о том, как я могу лучше контролировать это?

 ExecutorService pool = Executors.newFixedThreadPool(5);
  CompletionService<Properties> completion = new ExecutorCompletionService<Properties>(pool);

  for (String target : p.getTargetFiles()) {
   completion.submit(new PropertiesLoader(target, p));
  }

  for (@SuppressWarnings("unused")
  String target : p.getTargetFiles()) {
   Properties r = null;
   try {
    r = completion.take().get();
   } catch (InterruptedException e) {
    e.printStackTrace();
   } catch (ExecutionException e) {
    e.printStackTrace();
   }

   p.addTargetFilesProperties(r);
  }

  pool.shutdown();

Ответы [ 2 ]

3 голосов
/ 10 июня 2010

Основной смысл использования CompletionService.take - вернуть его в зависимости от того, что Future завершено, независимо от того, в каком порядке они были отправлены.Если вы хотите вернуть их по порядку, вы можете вообще их не использовать (вы можете даже не захотеть использовать CompletionService, но можете).Держите список Future объектов, возвращаемых из submit(), и вызывайте .get() для каждого;он будет блокироваться до тех пор, пока не станет доступен результат.

0 голосов
/ 10 июня 2010

При одновременной отправке нескольких задач в ThreadPoolExecutor вы не имеете реального контроля времени завершения, поскольку они выполняются несколькими потоками одновременно.Служба завершения возвращает их в порядке их завершения, который может варьироваться от одного выполнения к другому.Если вы решите выполнить задачу последовательно, порядок выполнения такой же, как и порядок активации.

- РЕДАКТИРОВАТЬ -

Если вы все еще хотите параллелизм, но хотите дождаться выполнения задачв определенном порядке, не используйте услугу завершения.Просто зациклите фьючерсы в требуемом порядке и вызовите их метод get (), который блокирует при необходимости.

...