Ответ
Параллельные стримы в Java — это механизм для выполнения операций над элементами коллекции (или другого источника) параллельно, используя несколько ядер процессора. Они основаны на внутреннем использовании пула потоков ForkJoinPool.commonPool().
Создание параллельного стрима:
List<String> list = Arrays.asList("a", "b", "c");
// Способ 1: Создать параллельный стрим из коллекции
list.parallelStream()
.forEach(System.out::println);
// Способ 2: Преобразовать существующий последовательный стрим в параллельный
list.stream()
.parallel()
.forEach(System.out::println);
Пример: Параллельное вычисление суммы:
long sum = LongStream.rangeClosed(1, 1_000_000)
.parallel() // Включаем параллельную обработку
.sum();
System.out.println("Сумма: " + sum);
Когда ИСПОЛЬЗОВАТЬ (лучшие случаи):
- Большой объем данных.
- «Дорогие» (CPU-intensive) операции над каждым элементом (сложные вычисления).
- Источник данных легко разделяется (например, ArrayList, массив, IntStream.range).
- Операция не зависит от порядка (ассоциативная и коммутативная, как
sum(),min()) или порядок контролируется (forEachOrdered). - Отсутствие состояния (stateless) и побочных эффектов в промежуточных и терминальных операциях.
Когда НЕ ИСПОЛЬЗОВАТЬ (подводные камни):
- Маленькие коллекции: Накладные расходы на распараллеливание превысят выгоду.
- Операции с зависимостями по порядку:
findFirst(),limit()в параллельном режиме могут работать медленнее. - Использование общих изменяемых состояний (shared mutable state): Приводит к состоянию гонки (race condition) и недетерминированным результатам.
// ПЛОХО: Race condition! List<Integer> unsafeList = new ArrayList<>(); IntStream.range(0, 1000).parallel().forEach(unsafeList::add); // Размер unsafeList будет меньше 1000
// ХОРОШО: Использовать потокобезопасные коллекции или reduce
List
* **Работа с блокирующими I/O операциями:** Потоки в `ForkJoinPool` не предназначены для этого, могут заблокировать все потоки пула.
**Вывод:** Параллельные стримы — мощный инструмент для ускорения CPU-задач на многоядерных системах, но требуют понимания их внутреннего устройства для корректного и эффективного применения.