Я запускаю список runnables, используя ExecutorService
, и сопоставляю все результаты, используя CompletableFuture
. Я хотел бы сопоставить, какой экземпляр CompletableFuture
запускал конкретный исполняемый файл.
Вот реальный код
public static void runTasks(final List<Runnable> tasks, final int threadCount) {
final ExecutorService es = Executors.newFixedThreadPool(threadCount);
final CompletableFuture<?>[] futures = tasks.stream()
.map(task -> CompletableFuture.runAsync(task, es))
.toArray(CompletableFuture[]::new);
try {
CompletableFuture.allOf(futures).join();
es.shutdown();
} catch (Exception e) {
System.exit(1);
}
}
У меня есть результаты, хранящиеся в переменной Futures
CompletableFuture<?>[] futures
Есть ли способ получить имя класса runnable, результат которого хранится в экземпляре будущего?
Я пытаюсь напечатать результат отдельной задачи следующим образом:
for (CompletableFuture future : futures) {
final boolean taskCompletedSuccessfully = future.isDone() && !(future.isCompletedExceptionally() || future.isCancelled());
LOGGER.info("Task completion status for {} : {}", <runnable class name>, (taskCompletedSuccessfully ? "SUCCESSFUL" : "FAILED"));
}
Невозможно получить какую-либо информацию о Runnable
, потому что CompletableFuture
не содержит никаких ссылок на него.
Таким образом, вам придется хранить будущее и исполняемый файл (или его имя класса) вместе в некоторой реализации Pair
, например:
final List<Pair<Runnable, CompletableFuture<Void>>> futures = tasks.stream()
.map(task -> new Pair<>(task, CompletableFuture.runAsync(task, es)))
.collect(toList());
try {
CompletableFuture.allOf(futures.stream().map(Pair::getB).toArray(CompletableFuture[]::new)).join();
} catch (Exception e) {
log.warn("At least one future failed", e);
}
es.shutdown();
futures.forEach(pair -> {
CompletableFuture<Void> future = pair.getB();
final boolean taskCompletedSuccessfully = !future.isCompletedExceptionally();
log.info("Task completion status for {} : {}", pair.getA().getClass().getSimpleName(), (taskCompletedSuccessfully ? "SUCCESSFUL" : "FAILED"));
});
Несколько заметок:
allOf()
также не удастся. Вы, вероятно, не хотите exit()
в этом случае - иначе у вас всегда будут регистрироваться только успешные задачи;allOf().join()
вам гарантировано, что isDone()
выполняется для всех задач, проверять не нужно;isCancelled()
(что здесь невозможно) подразумевает isCompletedExceptionally()
Спасибо за подтверждение моего предположения. Это должно работать.