Java parallelStream并行流

目录

前言

parallelStream() 是 Java 8 Stream API 提供的 并行流(Parallel Stream)

它可以让:

  • 一个集合的处理逻辑
  • 自动使用多线程并行执行

而不是单线程。


一、最简单理解

普通 stream:

java 复制代码
list.stream()

是 单线程

例如:

java 复制代码
1个线程处理20万数据

parallelStream:

java 复制代码
list.parallelStream()

是 多线程并行处理

例如:

text 复制代码
8核CPU
可能8个线程同时处理

二、举个最简单例子

普通 stream :

java 复制代码
list.stream()
    .map(x -> doSomething(x))
    .collect(Collectors.toList());

执行过程:

text 复制代码
第1条
第2条
第3条
...

按顺序一个个执行。


parallelStream :

java 复制代码
list.parallelStream()
    .map(x -> doSomething(x))
    .collect(Collectors.toList());

执行过程:

text 复制代码
线程1 -> 第1万条
线程2 -> 第2万条
线程3 -> 第3万条
...

同时执行。


三、parallelStream底层是什么?

底层使用: ForkJoinPool

默认:

text 复制代码
CPU核心数 - 1

例如:

8核CPU:

text 复制代码
默认7个工作线程

四、parallelStream什么时候适合?

适合:CPU密集型任务

例如:

  • 大量计算
  • 加密
  • 哈希
  • 复杂规则计算
  • 图片处理
  • 金额计算
  • 风控计算

例如:

java 复制代码
list.parallelStream()
    .map(this::calculate)

计算 很耗CPU。这时收益巨大。


五、什么时候不适合?

IO密集型

例如:

text 复制代码
数据库
Feign
HTTP
Redis
文件

例如:

java 复制代码
list.parallelStream()
    .forEach(x -> feign.call());

通常会更慢,甚至打爆数据库/接口。


六、为什么IO场景不适合?

因为,parallelStream 默认线程数:

text 复制代码
CPU核数

而IO:

text 复制代码
大量时间在等待

CPU其实没干活。


比如:

text 复制代码
线程1 等数据库
线程2 等网络
线程3 等Redis

CPU闲着。

所以:

parallelStream 对IO提升有限。


七、parallelStream的优势

1. 开发简单

不用:

text 复制代码
线程池
Future
CountDownLatch
CompletableFuture

一行搞定。


2. 自动线程调度

自动:

  • 分片
  • 分任务
  • 合并结果

3. CPU利用率高

例如:

8核CPU:

text 复制代码
单线程只用了1核

parallelStream:

text 复制代码
8核一起跑

八、parallelStream的缺点

很多人乱用。


缺点1:线程不受控

默认:

text 复制代码
ForkJoinPool.commonPool()

全局共享线程池。

可能:

text 复制代码
影响整个系统

缺点2:不适合数据库/Feign

例如:

java 复制代码
parallelStream()
    .forEach(x -> mapper.insert(x));

危险。

可能 瞬间几千SQL。


缺点3:线程安全问题

例如:

你这样写:

java 复制代码
List<String> result = new ArrayList<>();

list.parallelStream().forEach(x -> {
    result.add(x);
});

错误!

因为:

text 复制代码
ArrayList线程不安全

可能:

  • 数据丢失
  • 数组越界
  • ConcurrentModificationException

正确写法

用:

java 复制代码
collect(Collectors.toList())

因为 collect 内部处理了并发。


九、parallelStream为什么有时反而更慢?

因为:线程切换有成本

例如:

java 复制代码
1+1

这种极小任务。

还没切线程快。


所以:数据量小不要用

经验:

数据量 建议
<1000 通常没必要
1万+ 开始有收益
10万+ 常有明显收益

十、parallelStream不保证顺序

例如:

java 复制代码
list.parallelStream()
    .forEach(System.out::println);

输出:

text 复制代码
乱序

如果需要顺序:

java 复制代码
forEachOrdered()

但:性能会下降。


十一、真正高性能方案(推荐)

很多大系统:

不会直接用:

text 复制代码
parallelStream

而是:

自定义线程池 + CompletableFuture

因为:

  • 可控
  • 可监控
  • 可限流
  • 可隔离

例如:

java 复制代码
ExecutorService pool = Executors.newFixedThreadPool(8);

CompletableFuture.supplyAsync(() -> {
    return calculate();
}, pool);

十二、parallelStream vs 线程池

对比 parallelStream 线程池
简单 非常简单 较复杂
可控性
适合小功能 非常适合 一般
大型系统 不推荐滥用 推荐
自定义线程数 不方便 可以
隔离性

相关推荐
CS_Zero18 分钟前
C语言sizeof是函数吗?
c语言·开发语言
-今昭-1 小时前
《V2V 迁移实战:将 VMware 虚拟机转为 OpenStack 可用 Glance qcow2 镜像》
开发语言·python
zww89491112 小时前
匿名树洞系统开发实战:从需求分析到部署指南
java·eclipse
黑马程序员毕设3 小时前
基于Java的医院药品管理系统的优化设计与实现
java·开发语言·spring boot·小程序·架构·课程设计·毕设
木井巳3 小时前
【BFS/DFS 解决 FloodFill 算法】太平洋大西洋水流问题
java·算法·leetcode·深度优先·广度优先·宽度优先·推荐算法
白山编程大哥3 小时前
Java 集合算法:从排序、查找到底层原理的实战指南
java·python·算法
_Twink1e4 小时前
openJiuwen 实训营 Day 1 · WorkSwarm 入门教程
开发语言·c++·openjiuwen
devpotato4 小时前
缓存与数据库更新顺序不一致问题
java·数据库·redis
问天_观心4 小时前
大模型微调学习(一)
开发语言·人工智能·学习·语言模型·github
阿里嘎多学长4 小时前
2026-09-03 GitHub 热点项目精选
开发语言·程序员·github·代码托管