Получить экземпляр runnable из completablefuture

Я запускаю список 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"));
}
Основы программирования на Java
Основы программирования на Java
Java - это высокоуровневый объектно-ориентированный язык программирования, основанный на классах.
Концепции JavaScript, которые вы должны знать как JS программист!
Концепции JavaScript, которые вы должны знать как JS программист!
JavaScript (Js) - это язык программирования, объединяющий HTML и CSS с одной из основных технологий Всемирной паутины. Более 97% веб-сайтов используют...
0
0
158
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Невозможно получить какую-либо информацию о 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()

Спасибо за подтверждение моего предположения. Это должно работать.

Mahesh 23.05.2019 10:59

Другие вопросы по теме