Java Parallel Streams
·
ParallelStream(并行流) 是 Java 8 Stream API 提供的多核并行处理能力,底层基于 Fork/Join 分治框架,自动拆分任务、多线程执行、合并结果,无需手动写线程池 / 线程,大幅简化并发集合处理。
一、基础概念与用法
1. 两种创建方式
// 方式1:集合直接获取并行流
list.parallelStream()
// 方式2:普通串行流转并行流
list.stream().parallel()
2.用法:
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8);
// 并行流计算平方和
long sum = list.parallelStream()
.map(x -> x*x)
.reduce(0, Long::sum);
3. 串行 vs 并行流对比
| 特性 | 串行流 stream () | 并行流 parallelStream () |
|---|---|---|
| 执行线程 | 单线程顺序执行 | 多线程、多核并行执行 |
| 底层 | 无线程池 | ForkJoinPool.commonPool () 公共线程池 |
| 执行顺序 | 严格保证原顺序 | 无序执行(默认) |
| 性能 | 小数据快 | 大数据、计算密集快 |
| 线程安全 | 无需考虑 | 必须无状态、无共享可变变量 |
二、底层原理(Fork/Join 分治)
并行流执行流程:Fork 拆分 → 并行执行 → Join 合并
- Fork:把大集合递归拆分成足够小的子任务
- 并行执行:子任务提交到 ForkJoinPool,多核 CPU 并行处理
- Join:汇总所有子任务结果,得到最终结果
默认线程池配置
默认使用全局公共池:ForkJoinPool.commonPool()
- 并行线程数 = CPU 核心数 - 1
- 全局共享:所有并行流共用同一个线程池
- 可 JVM 参数修改全局并行度:
System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "8");
底层执行机制:工作窃取
这是并行流高效的核心:
- 每个线程有自己的任务队列
- 自己的任务做完了,会偷取其他线程的任务执行
- 最大化利用 CPU,避免线程空闲
三、适合使用并行流的场景(同时满足)
- 大数据量:一般 >1 万条元素(小数据并行开销>收益)
- 计算密集型:数学运算、转换、过滤;非 IO 阻塞(数据库、网络、文件)
- 无状态、无依赖:每个元素处理独立,不依赖其他元素
- 无序可接受:不严格要求处理 / 输出顺序
- 数据源支持高效拆分:
ArrayList、数组(最优);LinkedList 不适合并行(无法随机拆分)
四、不适合场景
- IO 密集、阻塞操作(数据库查询、RPC、网络、文件读写)公共线程池线程极少,阻塞会堵死全局所有并行流,Web 服务极易雪崩
- 小数据集:任务拆分 + 线程调度开销>并行收益,反而更慢
- 强顺序依赖:
findFirst()、limit()、forEach有序输出、sorted排序 - 修改外部共享可变变量 / 非线程安全集合(竞态条件、数据错乱)
- Web 高并发接口默认不建议直接用公共并行流(资源全局争用)
更多推荐




所有评论(0)