Stream的并行流一定比串行流更快吗?
面试回答¶
面试官: Stream 的并行流一定比串行流快吗?
你:
真不一定,甚至常常更慢。 并行流不是银弹,用不好比串行还拉胯。关键看:数据量、计算复杂度、数据结构和线程环境。
并行流为什么有时候反而慢?
并行流底层用 ForkJoinPool 公共线程池,把任务拆成多个子任务并发跑,跑完再合并结果。这套动作本身是有成本的:任务拆分、线程调度、线程上下文切换、结果合并。如果数据量小,这点计算可能还没这些开销大,就像叫了一帮人搬砖,结果砖就三块,光分活就花了半天。
具体哪些场景会踩坑?
-
数据量太小 拆分和合并的开销淹没了并行带来的增益。几百条数据,主线程一口气跑完可能只要 1ms,切成子任务各种调度却花了 5ms。
-
数据结构不易拆分
ArrayList这种基于数组的,能按索引快速切分,拆得利索。LinkedList、HashSet这种,结构松散,拆分过程要遍历,耗时剧增。 -
存在共享资源或线程同步 如果你在并行流里操作了非线程安全的集合,或者用到
synchronized,并行度直接归零,所有线程排队,还不如单线程跑。 -
CPU 核数不够 并行度受限于 CPU 核心数。单核机器上开并行流,就是“伪并行”,反而多了线程切换的开销。
-
计算太简单或 I/O 密集
filter、map这种简单计算,内存带宽和 CPU 缓存是瓶颈,多线程还破坏缓存局部性。I/O 密集任务用并行流也没用,瓶颈在磁盘或网络。
什么时候用并行流?
-
数据量超过 万级 以上。
-
计算是 CPU 密集 的,比如复杂对象转换、加解密、数学运算。
-
数据结构是 数组或 ArrayList,拆得快。
-
没有共享可变状态。
实战建议: 不确定就先别用。实在要用,JMH 压测对比,看实际吞吐量。别凭直觉上并行。
时序图:小数据量下,并行流为什么输给串行流

一句话:并行流是大炮,打蚊子不如苍蝇拍,得数据量大、计算重、数据结构利于拆分时才开炮。