На какой основе реализованы Parallel Stream в Java?

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

Ответ

Parallel Stream в Java реализован на основе Fork/Join Framework.

Ключевые компоненты:

  • ForkJoinPool — пул потоков из java.util.concurrent, используемый по умолчанию.
  • Work-stealing алгоритм — позволяет свободным потокам "воровать" задачи из очередей занятых, что улучшает балансировку нагрузки.
  • Количество потоков по умолчанию равно Runtime.getRuntime().availableProcessors().

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

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.parallelStream()
                 .mapToInt(Integer::intValue)
                 .sum();

Важные особенности и best practices:

  1. Порядок не гарантирован. Операции forEach или map выполняются в произвольном порядке. Для сохранения порядка используйте forEachOrdered, но это снижает производительность.
  2. Не для всех задач. Параллелизация эффективна для больших объемов данных и "тяжелых" операций. Для простых операций накладные расходы на разделение и объединение данных могут перевесить выгоду.
  3. Избегайте изменяемого состояния. Код внутри операций (например, лямбда в map) должен быть stateless и не модифицировать общие переменные, чтобы предотвратить состояние гонки (race condition).
  4. Использование кастомного пула:
    ForkJoinPool customPool = new ForkJoinPool(4);
    int result = customPool.submit(() -> 
        list.parallelStream().mapToInt(i -> i*2).sum()
    ).get();