Что проверяет вопрос про CompletionService

Кандидату дают массив из N задач и просят собрать результаты в порядке завершения, а не в порядке отправки. Первый инстинкт — держать List> и опрашивать каждый через get() по очереди. Работает, но если первая задача в списке выполняется дольше всех, весь поток стоит и ждёт её, хотя остальные результаты уже готовы.

CompletionService решает именно это. Он оборачивает Executor и внутреннюю BlockingQueue: каждая завершённая задача сама кладёт себя в очередь, а take() просто достаёт готовый Future — в порядке завершения, не отправки.

ExecutorService pool = Executors.newFixedThreadPool(4); CompletionService ecs = new ExecutorCompletionService<>(pool);

for (Task task : tasks) { ecs.submit(task); }

for (int i = 0; i < tasks.size(); i++) { Future done = ecs.take(); process(done.get()); }

На собесе спросят: что если одна задача упадёт с исключением? take() отдаст Future этой задачи сразу, как только она завершится — но get() на нём бросит ExecutionException. Нужно ловить исключение на каждой итерации отдельно, иначе одна упавшая задача остановит обработку всех остальных результатов.

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

Тренажёр: 600 вопросов, мок с таймером, план повторов

senior·base — что спрашивают на самом деле


В этом посте были ссылки, но мы их удалили по правилам Сетки