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