CompletableFuture, запуск асинхронного кода после «присоединения»

Через месяц у меня возникли проблемы только с Javascript/Typescript.

Например, давайте посмотрим этот фрагмент:

@Test
    public void testAsync(){
        CompletableFuture.supplyAsync(()->{
            try{
                Thread.sleep(10000);
                System.out.println("After some seconds");
            }catch(InterruptedException exc){
                return "Fail";
            }
            return "Done";
        }).thenAccept(s->System.out.println(s)).join();

        System.out.println("should write before After some seconds statement");
    }

Я ожидал, что последний system.out.println будет запущен до CompletableFuture, но он ожидает завершения Future.

Итак, что я получил: «Через несколько секунд» "Готово" «следует написать перед заявлением «После нескольких секунд»»

Что я хочу: «следует написать перед заявлением «После нескольких секунд»» «Через несколько секунд» "Готово"

Как я могу этого добиться?

Удалить join()? Или переместить его после печати?

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

Ответы 1

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

Сохраните будущее в переменной, распечатайте оператор, затем join() дождитесь результата:

CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
    try {
        Thread.sleep(10000);
        System.out.println("After some seconds");
    } catch (InterruptedException exc) {
        return "Fail";
    }
    return "Done";
}).thenAccept(s -> System.out.println(s));
System.out.println("should write before After some seconds statement");
future.join();

Что касается объяснения, в javadoc метода .join() говорится:

Returns the result value when complete, or throws an (unchecked) exception if completed exceptionally

То есть, если вы вызываете .join(), связанную с thenAccept(), это означает, что вы сначала дождетесь окончания supplyAsync(), затем thenAccept() и будете ждать такого результата через join().

Следовательно, вы достигнете своего System.out.println("should write before After some seconds statement"); сразу после завершения всех операций.

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

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