Какой ExecutorService используется в Parallel Stream в Java?

«Какой ExecutorService используется в Parallel Stream в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

По умолчанию Parallel Stream использует общий пул потоков JVM — ForkJoinPool.commonPool().

Ключевые детали:

  • Размер пула по умолчанию равен Runtime.getRuntime().availableProcessors() - 1.
  • Потоки в выводе будут иметь имена вида ForkJoinPool.commonPool-worker-*.

Пример использования по умолчанию:

List<Integer> numbers = List.of(1, 2, 3, 4, 5);
numbers.parallelStream()
       .forEach(n -> System.out.println(Thread.currentThread().getName()));

Как использовать кастомный пул: Вы можете выполнить стрим в своем экземпляре ForkJoinPool для контроля над параллелизмом.

ForkJoinPool customPool = new ForkJoinPool(4); // Пул с 4 потоками
customPool.submit(() -> 
    list.parallelStream().forEach(item -> process(item))
).get();
customPool.shutdown();

Почему ForkJoinPool? Его архитектура work-stealing оптимальна для рекурсивного разделения задач, что идеально подходит для параллельных операций со стримами.