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 合并

  1. Fork:把大集合递归拆分成足够小的子任务
  2. 并行执行:子任务提交到 ForkJoinPool,多核 CPU 并行处理
  3. Join:汇总所有子任务结果,得到最终结果

默认线程池配置

默认使用全局公共池:ForkJoinPool.commonPool()

  • 并行线程数 = CPU 核心数 - 1
  • 全局共享:所有并行流共用同一个线程池
  • 可 JVM 参数修改全局并行度:

System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "8");

底层执行机制:工作窃取

这是并行流高效的核心:

  • 每个线程有自己的任务队列
  • 自己的任务做完了,会偷取其他线程的任务执行
  • 最大化利用 CPU,避免线程空闲

三、适合使用并行流的场景(同时满足)

  1. 大数据量:一般 >1 万条元素(小数据并行开销>收益)
  2. 计算密集型:数学运算、转换、过滤;非 IO 阻塞(数据库、网络、文件)
  3. 无状态、无依赖:每个元素处理独立,不依赖其他元素
  4. 无序可接受:不严格要求处理 / 输出顺序
  5. 数据源支持高效拆分:ArrayList、数组(最优);LinkedList 不适合并行(无法随机拆分)

四、不适合场景

  1. IO 密集、阻塞操作(数据库查询、RPC、网络、文件读写)公共线程池线程极少,阻塞会堵死全局所有并行流,Web 服务极易雪崩
  2. 小数据集:任务拆分 + 线程调度开销>并行收益,反而更慢
  3. 强顺序依赖findFirst()limit()forEach有序输出、sorted排序
  4. 修改外部共享可变变量 / 非线程安全集合(竞态条件、数据错乱)
  5. Web 高并发接口默认不建议直接用公共并行流(资源全局争用)
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐