Java8 并行流(parallelStream)原理分析及线程池线数设置

您所在的位置:网站首页 javastream流用的多吗 Java8 并行流(parallelStream)原理分析及线程池线数设置

Java8 并行流(parallelStream)原理分析及线程池线数设置

2023-12-28 17:35| 来源: 网络整理| 查看: 265

这里是weihubeats,觉得文章不错可以关注公众号小奏技术,文章首发。拒绝营销号,拒绝标题党

我们都知道在java 使用strem流做多线程处理是非常方便的。

list.parallelStream().forEach(s -> { // 业务处理 });

但是parallelStream是如何实现多线程处理的呢?其实看源码我们会发现parallelStream是使用线程池ForkJoin来调度的,这里我们可以看源码看到 由于我们使用的 forEach,所以直接看类ForEachOps即可.当然其他方法比如reduce等会有不同的实现类,总的实现类是如下几个

java.util.stream.FindOps.FindOp java.util.stream.ForEachOps java.util.stream.MatchOps.MatchOp java.util.stream.ReduceOps.ReduceOp

里面基本都是调用 evaluateParallel方法 在这里插入图片描述 而 ForEachTask 继承关系如下 在这里插入图片描述 这里就找到了我们的答案,核心原理就是Fork Join 框架 而ForkJoinPool的默认线程数是CPU核数 - 1,无参构造方法就可以看出 在这里插入图片描述

如何设置 ForkJoinPool的线程数呢 这里有如下几种方法

直接构建自己的 ForkJoinPool CountDownLatch countDownLatch = new CountDownLatch(20); int cpu = Runtime.getRuntime().availableProcessors(); System.out.println(cpu); ForkJoinPool pool = new ForkJoinPool(2); List list = IntStream.range(0, 20).boxed().collect(Collectors.toList()); pool.submit(() -> { list.parallelStream().forEach(s -> { // 业务处理 System.out.println("thread:" + Thread.currentThread().getName() + "value" + s); countDownLatch.countDown(); }); }); countDownLatch.await();

在这里插入图片描述

可以看到始终只有2两个线程

使用参数设置 System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "5");

demo验证

System.setProperty( "java.util.concurrent.ForkJoinPool.common.parallelism", "5"); CountDownLatch countDownLatch = new CountDownLatch(5); List list = IntStream.range(0, 20).boxed().collect(Collectors.toList()); list.parallelStream().forEach(s -> { // 业务处理 System.out.println("thread:" + Thread.currentThread().getName() + "value" + s); countDownLatch.countDown(); }); countDownLatch.await(); int poolSize = ForkJoinPool.commonPool().getPoolSize(); System.out.println("Pool size: " + poolSize);

在这里插入图片描述 这里比较奇怪是设置了5个线程,虽然只有5个,但是主线程也加入了执行,这里暂时不做详细研究,有知道的欢迎留言



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3