一、前言
原文链接:https://mp.weixin.qq.com/s/_e9kRwNYggNDOz9BR8J-JQ
jdk8的parallelStream的执行线程是谁,你知道吗?
我们都知道 parallelStream 是并行流,相较stream而言,可以充分利用cpu资源,加快运行算速度。但是却从未探究过他的执行线程是谁这类问题。今天一起分析下。
二、验证与分析
1、先看一段普通程序:
public static void main(String[] args) {
List<Integer> nums = Arrays.asList(4, 1, 55, 49);
nums.parallelStream().forEach(System.out::println);// 输出上面数据
}
运行结果:因为是多线程运行,所以输出结果顺序与输入结果不一致。的确是并行执行的。
55
49
4
1
2、看看他的执行线程:
public static void main(String[] args) {
List<Integer> nums = Arrays.asList(4, 1, 55, 49);
nums.parallelStream().forEach(r ->
System.out.println(Thread.currentThread().getName() + "\t" + r)
);
}
运行结果:可以看到不仅使用了ForkJoinPool线程池里的线程,也使用了main线程。为什么呢?
main 55
ForkJoinPool.commonPool-worker-2 49
ForkJoinPool.commonPool-worker-1 1
main 4
引用《java 8 实战》的一段话:
并行流内部使用了默认的
ForkJoinPool
(7.2节会进一步讲到分支/合并框架),它默认的线程数量就是你的处理器数量,这个值是由Runtime.getRuntime().available- Processors()
得到的。 但是你可以通过系统属性java.util.concurrent.ForkJoinPool.common. parallelism
来改变线程池大小,如下所示:System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism","12");
这是一个全局设置,因此它将影响代码中所有的并行流。反过来说,目前还无法专为某个 并行流指定这个值。一般而言,让ForkJoinPool
的大小等于处理器数量是个不错的默认值, 除非你有很好的理由,否则我们强烈建议你不要修改它。
3、验证ForkJoinPool线程池
从ForkJoinPool类的无参构造中可以看出来,他的默认线程数量等于cpu核心数。
单独设置一下线程数:
public static void main(String[] args) {
// 单独设置ForkJoinPool线程数量
System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "1");
List<Integer> nums = Arrays.asList(4, 1, 55, 49);
nums.parallelStream().forEach(r -> {
System.out.println(Thread.currentThread().getName() + "\t" + r);
});
}
结果分析:可以看到生效了,因为处理多个任务时候,ForkJoinPool线程池中只拿出了1个线程来执行。线程池的容量为1。
其实也可以通过输出System.out.println(ForkJoinPool.commonPool().getPoolSize());
查看线程池大小是否生效
main 55
ForkJoinPool.commonPool-worker-1 1
main 49
ForkJoinPool.commonPool-worker-1 4
三、总结
-
parallelStream()默认线程池是ForkJoinPool线程池。
-
parallelStream() 执行程序的时候,并非都使用ForkJoinPool线程池里的线程来完成工作,也会使用其调用线程(eg:main线程)。
-
在高并发场景,如果某个耗时的接口中使用了并行流。执行业务逻辑的线程可以是来自容器的线程(eg;tomcat),会加速消耗容器线程,也会加速cpu与内存的消耗,严重的话可能导致系统崩溃。因此在使用时需要注意此类场景。
-
ForkJoinPool线程池的默认线程数是cpu核心数(
Runtime.getRuntime().availableProcessors()
)
获取更多内容,请关注微信公众号。搜索“码圈小橙子,这里会不时的更新。