CompletableFuture не выполняется

У меня очень странная проблема с CompletableFuture.

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Main {

    final static ExecutorService executor = Executors.newCachedThreadPool();

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            final CompletableFuture withoutExecutor = doSomethingOne(i);
//      final CompletableFuture withExecutor = doSomethingTwo(i);
        }
    }

    private static CompletableFuture doSomethingOne(final int i) {
        return CompletableFuture.runAsync(() -> {
            System.out.println("Without Executor " + i);
        });
    }

    private static CompletableFuture doSomethingTwo(final int i) {
        return CompletableFuture.runAsync(() -> {
            System.out.println("With Executor " + i);
        }, executor);
    }
}

Когда main выполняется, он ничего не печатает (withoutExecutor CompletableFuture даже не выполняется). Но когда я раскомментирую withExecutor, оба CompletableFuture работают как положено. Что мне не хватает?

У меня похожая проблема в моем личном проекте, но общая идея та же. В настоящее время я использую исполнитель с моими CompletableFuture в проекте, и они работают только в течение определенного периода времени, а затем полностью перестают работать (даже отладчик не достигает точки останова в CompletableFuture). Мне нужна асинхронная фоновая задача, ожидание не вариант, так как CompletableFuture запускается через REST API в моем проекте, и я должен вернуть результат сохранения истории как можно скорее.

Предположения, но, возможно, связанные с окончанием main (так что вся программа заканчивается) до того, как CompleteFuture успеет запуститься. Это также может зависеть от того, создает ли пул потоков рабочих как поток демона или не-демона.

Andrew S 20.04.2023 18:41

Дубликат относится к коду в вашем вопросе. Я не уверен, решит ли это проблему в вашем реальном проекте. Подскажите так или иначе, пожалуйста.

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

Ответы 1

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

Попробуйте этот код

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer;

public class Main {

    private static final ExecutorService executor = Executors.newCachedThreadPool();

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            Consumer<Integer> consumer = result -> System.out.println("Result: " + result);
            doSomething(i)
                    .thenAcceptAsync(consumer, executor);
        }
        System.out.println("Main thread is not blocked");
    }

    private static CompletableFuture<Integer> doSomething(final int i) {
        return CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(2500);
            } catch (InterruptedException interruptedException) {
                interruptedException.printStackTrace();
            }
            return i * 3;
        }, executor);
    }
}

Спасибо, это работает. Но проблема в том, что это блокирующий механизм из-за join(). Мне нужно что-то вроде асинхронной фоновой задачи

Hasham Rasheed 20.04.2023 18:44

@HashamRasheed Если цель состоит в том, чтобы иметь асинхронную фоновую задачу, вы можете изменить код, чтобы использовать функцию обратного вызова для обработки результатов после завершения CompletableFuture. Позвольте мне изменить свой ответ, чтобы продемонстрировать вам.

Zufar Sunagatov 20.04.2023 18:46

@HashamRasheed попробуйте обновленный код, пожалуйста :-)

Zufar Sunagatov 20.04.2023 18:54

@HashamRasheed все хорошо? Дайте мне знать, если я могу вам помочь. :-)

Zufar Sunagatov 20.04.2023 18:59

@HashamRasheed Добро пожаловать! Рад помочь вам! :) Дайте мне знать, если у вас возникнут другие проблемы, пожалуйста.

Zufar Sunagatov 20.04.2023 19:16

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