Этап 6 из 11 · ≈ 8 ч

Пулы потоков и CompletableFuture

Основа с Middle

ExecutorService, размеры пулов, Future и CompletableFuture, ThreadLocal и Fork/Join.

Что важно знать

  • Пул с неограниченной очередью прячет перегрузку до OutOfMemoryError.
  • Размер пула: вычисления — около числа ядер, ожидание ввода-вывода — больше.
  • thenApply, thenCompose, allOf, exceptionally, orTimeout.
  • Без своего executor CompletableFuture уходит в общий ForkJoinPool.
  • ThreadLocal в пуле надо очищать.

Критерии освоения

Middle ≈ 8 ч

  • Создаёт пулы с ограниченной очередью и политикой отказа, подбирает размер под задачи
  • Строит асинхронные цепочки на CompletableFuture с обработкой ошибок и таймаутами
  • Объясняет утечку ThreadLocal в пулах потоков

Практика. Параллельно опросить 5 внешних сервисов через CompletableFuture с общим таймаутом и частичными результатами.

Проверка знаний

Войдите, чтобы пройти тест: сданный тест отмечает тему пройденной на карте и в ИПР.

Вопросы с собеседований

Смотреть все
Почему задачи отдают в пул потоков, а не создают поток на каждую?Junior

Пул переиспользует потоки и ограничивает их число: создание потока дорого, а неограниченный рост убивает приложение.

Полный разбор
В чём опасность ThreadLocal в пуле потоков?Middle

Поток в пуле переиспользуется: значение ThreadLocal, не очищенное после задачи, протекает в следующую задачу (чужой пользователь, транзакция) и удерживает память. Правило: try { set } finally { remove() }.

Полный разбор
Что такое Fork/Join framework и work stealing?Senior

Fork/Join — рекурсивное деление задачи на подзадачи (fork) с последующим объединением результатов (join). Work stealing: у каждого рабочего потока своя двусторонняя очередь, а освободившийся поток крадёт задачи с хвоста чужой очереди — нагрузка балансируется…

Полный разбор
Что представляет собой объект Future?Junior

Future — ссылка на результат, который появится позже: можно проверить готовность, дождаться значения или отменить задачу.

Полный разбор
Какое ограничение Future решает CompletableFuture?Middle

Future — дескриптор результата с единственным способом получить значение: блокирующий get(). CompletableFuture позволяет описать цепочку продолжений (thenApply, thenCompose, thenCombine, allOf), которая выполнится по готовности, — без блокировки потока.

Полный разбор
Почему опасно выполнять блокирующие операции в стадиях CompletableFuture без явного Executor?Senior

Async-стадии без Executor выполняются в ForkJoinPool.commonPool — он общий на всю JVM и размером примерно число ядер − 1. Блокирующие вызовы (HTTP, БД, get чужого future) занимают его потоки, и встаёт всё, что им пользуется: другие цепочки, parallel stream…

Полный разбор

Разборы темы

← Вся карта «Java»

Партнёр платформы

Разбор собеседования с sotto

После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.

Разбор собеседования