Вы можете связать столько независимых заданий, сколько хотите, для определенного необходимого задания, например.
CompletableFuture<Foo> base=CompletableFuture.supplyAsync(() -> new Foo());
Collections.nCopies(N, base).forEach(f -> f.thenAcceptAsync(foo -> work(foo)));
создаст N
параллельных задания, одновременно вызывая work(foo)
, после завершения исходного задания, которое предоставляет экземпляр Foo
.
Но имейте в виду, что базовая структура будет учитывать количество доступных ядер ЦП для определения размера пула потоков, фактически выполняющего параллельные задания, поэтому, если N > #cores
, некоторые из этих заданий могут выполняться одно за другим.
Если работа связана с вводом-выводом, поэтому вы хотите иметь большее количество параллельных потоков, вы должны указать своего собственного исполнителя.
Цикл nCopies
/forEach
не обязателен, подойдет и цикл for
, но он дает подсказку о том, как обрабатывать последующие задания, которые зависят от завершения всех этих параллельных заданий:
CompletableFuture<Foo> base=CompletableFuture.supplyAsync(() -> new Foo());
CompletableFuture<Void> all = CompletableFuture.allOf(
Collections.nCopies(N, base).stream()
.map(f -> f.thenAcceptAsync(foo -> work(foo)))
.toArray(CompletableFuture<?>[]::new));
Теперь вы можете использовать all
для проверки завершения всех заданий или цепочки дополнительных действий.
person
Holger
schedule
16.06.2016
CompletableFuture.allOf(parallel).join();
, когда вы не хотите ждать завершения? Никто не требует, чтобы вы ждали… - person Holger   schedule 16.06.2016