Какой у вас опыт работы с CompletableFuture в Java?

«Какой у вас опыт работы с CompletableFuture в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

CompletableFuture — это реализация Future и CompletionStage, предоставляющая API для асинхронного, неблокирующего программирования, композиции задач и обработки исключений.

Основные паттерны использования:

  1. Запуск асинхронной задачи:

    CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> fetchData());
  2. Создание цепочки преобразований и обработки:

    CompletableFuture.supplyAsync(() -> fetchUserData(userId))
        .thenApply(user -> enrichUserData(user)) // Синхронное преобразование
        .thenApplyAsync(data -> saveToDatabase(data), executor) // Асинхронное в другом пуле
        .thenAccept(result -> log.info("Saved: {}", result)) // Финальное действие
        .exceptionally(ex -> { // Обработка исключений
            log.error("Failed", ex);
            return null;
        });
  3. Комбинация нескольких будущих результатов:

    // Ожидание завершения всех
    CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1, future2);
    // Ожидание первого завершенного
    CompletableFuture<Object> anyFuture = CompletableFuture.anyOf(future1, future2);
    // Объединение результатов двух независимых задач
    CompletableFuture<String> combined = future1.thenCombine(future2, (res1, res2) -> res1 + res2);

Ключевые методы: thenCompose (плоское преобразование), handle/whenComplete (обработка результата/исключения), orTimeout/completeOnTimeout (таймауты). Важно управлять пулом потоков через Executor, чтобы не использовать общий ForkJoinPool.commonPool() в ресурсоемких задачах.