Получить доступ

Future и CompletableFuture

Ограничения Future, асинхронная композиция CompletableFuture, async-варианты с пулами и обработка ошибок.

Future и его ограничения

submit(Callable) возвращает Future — дескриптор будущего результата с get() (блокирующее ожидание), isDone() и cancel(). Это базовый способ получить результат асинхронной задачи.

Ограничения Future жёсткие: get() блокирует поток, нельзя задать колбэк на завершение и нельзя композировать несколько Future в конвейер без блокировок. Именно это решает CompletableFuture.

CompletableFuture: асинхронный результат

CompletableFuture — это Future, на который можно навешивать продолжения, не блокируя поток. Задачу запускают через supplyAsync (с результатом) или runAsync (без), а дальше описывают конвейер преобразований, который выполнится по готовности.

Это сдвиг от «дождитесь и заберите» к «опишите, что сделать с результатом, когда он появится».

CompletableFuture
    .supplyAsync(() -> loadUser(id), pool)
    .thenApply(User::name)
    .thenAccept(System.out::println);

Композиция

thenApply трансформирует результат (как map). thenCompose сцепляет зависимую асинхронную операцию, возвращающую свой CompletableFuture (как flatMap) — без него получился бы вложенный CompletableFuture<CompletableFuture<…>>. thenCombine объединяет два независимых результата.

Для групп: allOf ждёт завершения всех, anyOf — первого. Так строят и параллельные веера, и последовательные цепочки.

async-варианты и пул

У каждого шага есть *Async-вариант (thenApplyAsync), который выполняет продолжение в пуле, а не в потоке, завершившем предыдущий шаг. Без явного Executor используется общий ForkJoinPool.commonPool.

Важное правило: не выполнять блокирующие операции в common pool — он маленький (по числу ядер) и общий на весь процесс; для блокирующих шагов передавайте отдельный пул.

Обработка ошибок

Исключение внутри стадии заворачивается в CompletionException и пробрасывается по цепочке. Его обрабатывают: exceptionally (подставить запасное значение), handle (получить и результат, и исключение), whenComplete (побочный эффект без изменения результата).

Забытая обработка ошибки в CompletableFuture — частый баг: исключение «теряется», если результат никто не забрал.

Как отвечать на собеседовании

Назовите ограничения Future (блокирующий get, нет композиции) как мотивацию CompletableFuture, различите thenApply/thenCompose/thenCombine (map/flatMap/zip) и allOf/anyOf, подчеркните про *Async с явным пулом и запрет блокировок в commonPool, и перечислите exceptionally/handle/whenComplete для ошибок.

Вопросы по теме

Читайте также

Закрытая бета

Знать тему — половина дела

На живом собеседовании sotto слышит вопрос интервьюера и показывает короткий ответ и план. Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем