Мой компьютер с четырьмя ядрами (FYI)
CompletableFuture будет использовать ForkJoinPool.commonPool()
в качестве официального документа указывает:
Все асинхронные методы безявный аргумент Executor выполняется с помощью ForkJoinPool.commonPool () (если только он не поддерживает уровень параллелизма как минимум два, и в этом случае создается новый поток для выполнения каждой задачи).
Я отладил и обнаружил следующий код из CompletableFuture.supplyAsync(Supplier<U> supplier)
private static final boolean useCommonPool =
(ForkJoinPool.getCommonPoolParallelism() > 1);
/**
* Default executor -- ForkJoinPool.commonPool() unless it cannot
* support parallelism.
*/
private static final Executor asyncPool = useCommonPool ?
ForkJoinPool.commonPool() : new ThreadPerTaskExecutor();
Что означает, что parallelStream
всегда использует ForkJoinPool.commonPool()
, но вот почему это быстрее.
Я попытался распечатать их и обнаружил, что только три нити при использовании CompletableFuture:
private static int concurrencyGet() {
List<CompletableFuture<Integer>> futureList = IntStream.rangeClosed(0, 10).boxed()
.map(i -> CompletableFuture.supplyAsync(() -> getNumber(i)))
.collect(Collectors.toList());
return futureList.stream().map(future -> future.join()).reduce(0, Integer::sum);
}
Но ParallelsStream используют четыре , включая основная нить.
Я предполагаю, что в CompletableFuture.supplyAsync()
ForkJoinPool.getCommonPoolParallelism()
составляет всего три , в то время как основной поток принимает один из четырех, поскольку он асинхронен .
Но parallelStream будет использовать все четыре , поскольку он не асинхронный .
Это правильно?Интересно, есть ли официальные документы по этому вопросу?
Спасибо за помощь.