Как контролировать заказы, в которых фьючерсы Java «представлены»?
Вопрос
В этом примере я отправляю несколько файлов в мой объект сравнения. Все все работает нормально, за исключением того, что я заметил, что порядок, в котором подаются файлы, не всегда TEH, тот же порядок, в котором они возвращаются. Любые предложения о том, как я могу лучше контролировать это?
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();
Решение
Основная точка использования CompletionService.take
это вернется в зависимости от того Future
закончил, независимо от того, какой порядок они были представлены. Если вы хотите вернуть их, чтобы вы могли бы также не использовать это вообще (вы даже не хотите использовать CompletionService
Вообще, но можно). Держите список Future
Объекты возвращаются из submit()
и позвонить .get()
на каждом; Он будет блокировать, пока результат не будет доступен.
Другие советы
При отправке нескольких задач в ThreadPoolExecuturexustor сразу у вас нет реального управления временами завершения, поскольку они выполняются одновременно несколькими потоками. Сервис завершения возвращает их в завершении заказа, что может варьироваться от одного исполнения в другое. Если вы решите выполнить задачу последовательно, заказ завершения совпадает с порядком активации.
--РЕДАКТИРОВАТЬ--
Если вы все еще хотите параллелизма, но хотите дождаться задач в определенном порядке, не используйте службу завершения. Просто петлю на фьючерсах в требуемом порядке, и позвоните в методе GET (), в которых при необходимости блокируется.