Вопрос проверяет понимание параллелизма, ограничений Stream API и умение оценивать реальные выгоды от распараллеливания.
Параллельные стримы позволяют обрабатывать элементы коллекции в нескольких потоках автоматически. Они имеют смысл только для CPU-bound задач с большим объёмом данных и независимыми операциями. Для I/O, синхронизаций и небольших коллекций они чаще вредят. Также важно помнить, что используется общий ForkJoinPool. Использовать их нужно осторожно.
Параллельные стримы — это не универсальное решение для ускорения кода.
Parallel Stream — это Stream, который обрабатывает элементы коллекции параллельно, используя ForkJoinPool.commonPool.
Создание:
list.parallelStream()
.map(x -> x * x)
.sum();
Перед применением важно оценить несколько факторов.
Тип задачи
CPU-bound операции
Тяжёлые вычисления
Нет блокировок
Размер данных
Тысячи и миллионы элементов
Мелкие коллекции не дают выигрыша
Независимость операций
Нет изменения общего состояния
Нет синхронизации
I/O операции
Работа с БД
HTTP-запросы
Файлы
Синхронизация
synchronized
lock
Общие коллекции
Ограничения пула
Используется ForkJoinPool.commonPool
Можно повлиять на другие части приложения
Непредсказуемая производительность
Сложность отладки
Побочные эффекты
forEach с изменением внешних переменных
Плохой пример:
list.parallelStream()
.forEach(x -> sharedList.add(x)); // race condition
Параллельные стримы полезны для вычислений без побочных эффектов и с большим объёмом данных. Во всех остальных случаях лучше использовать явные ExecutorService или обычные стримы.