Что проверяет вопрос про 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 — что спрашивают на самом деле
В этом посте были ссылки, но мы их удалили по правилам Сетки