Как создаются параллельные потоки (Parallel Stream) в Java?

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

Ответ

Параллельные потоки в Java Stream API создаются двумя основными способами, которые используют под капотом общий ForkJoinPool.

Способы создания:

  1. Метод Collection.parallelStream() — самый частый способ создать параллельный поток напрямую из коллекции.

    List<String> list = Arrays.asList("A", "B", "C");
    list.parallelStream()
        .forEach(System.out::println); // Элементы обрабатываются параллельно
  2. Метод Stream.parallel() — преобразует существующий последовательный поток в параллельный.

    Stream.of("A", "B", "C")
          .parallel() // Преобразование в параллельный поток
          .forEach(System.out::println);

Важные детали реализации:

  • По умолчанию используется ForkJoinPool.commonPool() — общий пул потоков для всего приложения.
  • Количество потоков в общем пуле равно количество_ядер_процессора - 1.
  • Можно использовать свой ForkJoinPool для изоляции задачи:
    ForkJoinPool customPool = new ForkJoinPool(4);
    customPool.submit(() -> 
        list.parallelStream().forEach(...) // Работает в customPool
    ).get();

Когда использовать: Параллельные потоки эффективны для CPU-интенсивных задач с большими объемами данных, где затраты на распараллеливание окупаются. Для простых операций или IO-задач они могут дать обратный эффект из-за накладных расходов.