CompletableFuture join(), похоже, не ждет завершения

Я столкнулся с проблемой, когда последовательно выполняю два объекта CompletableFuture. Мое намерение состоит в том, чтобы завершить первое и только после этого приступить к выполнению второго. Другими словами, второе зависит от завершения первого.

Я не могу поделиться точным кодом, но вот упрощенная версия того, что я делаю:

public static void main() {
    Set<Object> firstSet = /* ... */
    Set<Object> secondSet = /* ... */

    CompletableFuture<Void> firstFuture = getFuture(firstSet);
    CompletableFuture<Void> secondFuture = getFuture(secondSet);

    // Want to ensure that secondFuture does not begin executing until 
    // all of the futures in firstFuture have completed 
    firstFuture.join();
    secondFuture.join();
}

CompletableFuture<Void> getFuture(Set<Object> listOfObjects) {

    List<CompletableFuture<Void>> futures = listOfObjects
    .stream()
    .map(object -> CompletableFuture.runAsync(getRunnableForObject(object), executorService))
    .collect(Collectors.toList());

    CompletableFuture<Void> future = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));
    return future;
}

Runnable getRunnableForObject(Object obj) {
   // assume this returns a custom runnable whose execution behavior depend on the object parameter
}

При запуске кода я вижу, что иногда журналы, напечатанные во время выполнения firstFuture.join(), имеют отметку времени, которая позже, чем некоторые журналы, напечатанные во время secondFuture.join(). Я ожидаю, что мы никогда не увидим какие-либо журналы, напечатанные во время secondFuture, перед любыми журналами, напечатанными во время firstFuture.

Я думал, что firstFuture.join() гарантирует, что будущее завершится полностью, прежде чем синхронно перейти к secondFuture.join(), но, возможно, я неправильно понимаю. Кто-нибудь может посоветовать?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Этот код запускает фоновые задачи для обоих наборов, чтобы они выполнялись одновременно:

CompletableFuture<Void> firstFuture = getFuture(firstSet);
CompletableFuture<Void> secondFuture = getFuture(secondSet);

Простой способ обеспечить первый/второй порядок, просто переключив эти строки на:

CompletableFuture<Void> firstFuture = getFuture(firstSet);
firstFuture.join();

CompletableFuture<Void> secondFuture = getFuture(secondSet);
secondFuture.join();

Спасибо! Кажется, это решает проблему для меня.

user313 12.04.2023 23:01

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