В каком потоке выполнится ваш код после await() на CompletableFuture.allOf
allOf не возвращает результат — он возвращает CompletableFuture, который завершается, когда завершились все переданные футуры. Вопрос в том, кто именно его завершает и в каком потоке окажется код, навешенный дальше через thenApply или thenRun.
Завершает allOf тот поток, который финишировал последним из переданных футур. Если три задачи считались в разных пулах, четвёртый код выполнится в потоке той задачи, что закончилась позже остальных — не в вызывающем потоке, не в отдельном новом.
Это ловит на живых задачах: если одна из футур уже завершена к моменту вызова allOf (например, была закэширована), а остальные ещё считаются, итоговый callback всё равно выполнится в потоке самой долгой задачи.
CompletableFuture f1 = CompletableFuture.supplyAsync(() -> slow(), pool1); CompletableFuture f2 = CompletableFuture.supplyAsync(() -> fast(), pool2);
CompletableFuture.allOf(f1, f2) .thenRun(() -> System.out.println(Thread.currentThread().getName())); // выведет имя потока из pool1, если f1 дольше
Спросят следом: что будет, если один из вложенных футур завершится исключением. allOf не прокинет его сам — исключение всплывёт только при вызове join() или get() на результирующем future, и если его не читать, оно так же тихо потеряется, как при submit без get().
Поток продолжения зависит от того, какая задача закончилась последней — это не вызывающий поток и не отдельный планировщик.
senior·base — что спрашивают на самом деле
В этом посте были ссылки, но мы их удалили по правилам Сетки