您的位置:首页 >怎么区分 Stream 流的并行处理 parallel() 与普通处理在底层线程池(ForkJoinPool)的共用
发布于2026-04-29 阅读(0)
扫一扫,手机访问

简单来说,并行流的 parallel() 并不创建新线程池,而是直接复用 JVM 全局共享的 ForkJoinPool.commonPool()。普通流(stream())则完全是另一回事——它只在当前调用线程中顺序执行,根本不涉及任何线程池和并发调度。
所有未显式指定线程池的并行流,底层都走同一个 ForkJoinPool 实例:ForkJoinPool.commonPool()。这里有个关键点:这个池子不是每次调用时新建的,而是 JVM 启动时初始化一次的静态共享池。
Runtime.getRuntime().a vailableProcessors() - 1。举个例子,在一台8核的机器上,默认就是7个并行线程。System.setProperty("ja va.util.concurrent.ForkJoinPool.common.parallelism", "12");ForkJoinTask.invoke() 和 CompletableFuture 的默认异步执行。像 list.stream().filter(...).map(...) 这样的普通流操作,整个链路都在当前线程内完成。没有任务提交、没有工作窃取、也没有线程调度的开销。它的执行模型和传统的 for 循环一样,是纯同步、单线程且行为可预测的。
想亲眼看看是不是真的共用一个池子?可以通过打印线程名或检查池状态来验证:
.forEach(x -> System.out.println(Thread.currentThread().getName()))ForkJoinPool.commonPool-worker-1 这样的名称。ForkJoinPool.commonPool().toString() 和 list.parallelStream().count() 前后,池子的 activeThreadCount 或 poolSize 等状态值会发生变化。这里有个容易混淆的地方:调用 .parallel().sequential() 只是让后续操作退回到单线程顺序执行模式。但是,整个流可能已经在 commonPool 中启动过 fork/join 分支了。这个方法并不会释放线程,也不会切换到其他池子——它的作用仅仅是“不再进行并行调度”,而实际执行任务的线程,很可能还是 commonPool 里的某个 worker。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
9