iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >parallelStream的坑实例分析
  • 642
分享到

parallelStream的坑实例分析

2023-06-27 10:06:27 642人浏览 安东尼
摘要

这篇文章主要讲解了“parallelStream的坑实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“parallelStream的坑实例分析”吧!很多同学喜欢使用lambda表达式,它

这篇文章主要讲解了“parallelStream的坑实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“parallelStream的坑实例分析”吧!

很多同学喜欢使用lambda表达式,它允许你定义短小精悍的函数,体现你高超的编码水平。当然,这个功能在某些以代码行数来衡量工作量的公司来说,就比较吃亏一些。

比如下面的代码片段,让人阅读的时候就像是读诗一样。但是一旦用不好,也是会要命的。

List<Integer> transactionsIds =widgets.stream()             .filter(b -> b.getColor() == RED)             .sorted((x,y) -> x.getWeight() - y.getWeight())             .mapToInt(Widget::getWeight)             .sum();

这段代码有一个关键的函数,那就是stream。通过它,可以将一个普通的 list ,转化为流,然后就可以使用类似于管道的方式对 list 进行操作。总之,用过的都说好。

问题来了

假如我们把stream换成parallelStream,会发生什么情况?

根据字面上的意思,流会从串行 变成并行

既然是并行,那用屁股想一想,就知道这里面肯定会有线程安全问题。不过我们这里讨论的并不是要你使用线程安全的集合,这个话题太低级。现阶段,知道在线程不安全的环境中使用线程安全的集合,已经是一个基本的技能。

这次踩坑的地方,是并行流的性能问题。

我们用代码来说话。

下面的代码,开启了8个线程,这8个线程都在使用并行流进行数据计算。在执行的逻辑中,我们让每个任务都 sleep 1秒钟,这样就能够模拟一些 I/O 请求的耗时等待。

使用stream,程序会在30秒后返回,但我们期望程序能够在1秒多返回,因为它是并行流,得对得起这个称号。

测试发现,我们等了好久,任务才执行完毕。

static void paralleTest() {    List<Integer> numbers = Arrays.asList(            0, 1, 2, 3, 4, 5, 6, 7, 8, 9,            10, 11, 12, 13, 14, 15, 16, 17, 18, 19,            20, 21, 22, 23, 24, 25, 26, 27, 28, 29    );    final long begin = System.currentTimeMillis();    numbers.parallelStream().map(k -> {        try {            Thread.sleep(1000);            System.out.println((System.currentTimeMillis() - begin) + "ms => " + k + " \t" + Thread.currentThread());        } catch (InterruptedException e) {            e.printStackTrace();        }        return k;    }).collect(Collectors.toList());}public static void main(String[] args) {//    System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "20");    new Thread(() -> paralleTest()).start();    new Thread(() -> paralleTest()).start();    new Thread(() -> paralleTest()).start();    new Thread(() -> paralleTest()).start();    new Thread(() -> paralleTest()).start();    new Thread(() -> paralleTest()).start();    new Thread(() -> paralleTest()).start();    new Thread(() -> paralleTest()).start();}

实际上,在不同的机器上执行,这段代码花费的时间都不一样。

既然是并行,那肯定得有个并行度。太低了,体现不到并行的能能力;太大了,又浪费了上下文切换的时间。我是很沮丧的发现,很多高级研发,将线程池的各种参数背的滚瓜烂熟,各种调优,竟然敢睁一只眼闭一只眼的在 I/O 密集型业务中用上parallelStream

要了解这个并行度,我们需要查看具体的构造方法。在ForkJoinPool类中找到这样的代码。

try {  // ignore exceptions in accessing/parsing properties    String pp = System.getProperty        ("java.util.concurrent.ForkJoinPool.common.parallelism");    if (pp != null)        parallelism = Integer.parseInt(pp);    fac = (ForkJoinWorkerThreadFactory) newInstanceFromSystemProperty(        "java.util.concurrent.ForkJoinPool.common.threadFactory");    handler = (UncaughtExceptionHandler) newInstanceFromSystemProperty(        "java.util.concurrent.ForkJoinPool.common.exceptionHandler");} catch (Exception ignore) {}if (fac == null) {    if (System.getSecurityManager() == null)        fac = defaultForkJoinWorkerThreadFactory;    else // use security-managed default        fac = new InnocuousForkJoinWorkerThreadFactory();}if (parallelism < 0 && // default 1 less than #cores    (parallelism = Runtime.getRuntime().availableProcessors() - 1) <= 0)    parallelism = 1;if (parallelism > MAX_CAP)    parallelism = MAX_CAP;

可以看到,并行度到底是多少,是由下面的参数来控制的。如果无法获取这个参数,则默认使用 CPU个数-1 的并行度。

可以看到,这个函数是为了计算密集型业务去设计的。如果你喂给它一大堆任务,它就会由并行执行退变成类似于串行的效果。

-Djava.util.concurrent.ForkJoinPool.common.parallelism=N

即使你使用-Djava.util.concurrent.ForkJoinPool.common.parallelism=N设置了一个初始值大小,它依然有问题。

因为,parallelism这个变量是 final 的,一旦设定,不允许修改。也就是说,上面的参数只会生效一次。

张三可能使用下面的代码,设置了并行度大小为20

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

李四可能用同样的方式,设置了这个值为30。那实际在项目中用的是哪个值,那就得问 JVM 是怎么加载的类信息了。

这种方式并不太非常靠谱。

一种解决方式

我们可以通过提供外置的forkjoinpool,也就是改变提交方式,来实现不同类型的任务分离。

代码如下所示,通过显式的代码提交,即可实现任务分离。

ForkJoinPool pool = new ForkJoinPool(30);final long begin = System.currentTimeMillis();try {    pool.submit(() ->            numbers.parallelStream().map(k -> {                try {                    Thread.sleep(1000);                    System.out.println((System.currentTimeMillis() - begin) + "ms => " + k + " \t" + Thread.currentThread());                } catch (InterruptedException e) {                    e.printStackTrace();                }                return k;            }).collect(Collectors.toList())).get();} catch (InterruptedException e) {    e.printStackTrace();} catch (ExecutionException e) {    e.printStackTrace();}

这样,不同的场景,就可以拥有不同的并行度。这种方式和CountDownLatch有异曲同工之妙,我们需要手动管理资源。

感谢各位的阅读,以上就是“parallelStream的坑实例分析”的内容了,经过本文的学习后,相信大家对parallelStream的坑实例分析这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

--结束END--

本文标题: parallelStream的坑实例分析

本文链接: https://www.lsjlt.com/news/309768.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • parallelStream的坑实例分析
    这篇文章主要讲解了“parallelStream的坑实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“parallelStream的坑实例分析”吧!很多同学喜欢使用lambda表达式,它...
    99+
    2023-06-27
  • Python中的坑实例分析
    今天小编给大家分享一下Python中的坑实例分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。坑从何来最初是想要为自己的一个...
    99+
    2023-06-27
  • Shell中exit 0坑实例分析
    这篇文章主要讲解了“Shell中exit 0坑实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Shell中exit 0坑实例分析”吧!在 shell 编程中,需慎用...
    99+
    2023-06-29
  • Java中Objects.equals踩坑实例分析
    今天小编给大家分享一下Java中Objects.equals踩坑实例分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1. ...
    99+
    2023-06-29
  • Docker部署服务的坑实例分析
    这篇文章主要讲解了“Docker部署服务的坑实例分析 ”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Docker部署服务的坑实例分析 ”吧!本项目采用的是s...
    99+
    2022-10-19
  • Flutter中关于angle的坑实例分析
    这篇“Flutter中关于angle的坑实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Flutter中关于angle...
    99+
    2023-07-02
  • Next.js项目实战踩坑的示例分析
    这篇文章主要介绍Next.js项目实战踩坑的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!前言github: https://github.com/code-coder/ne...
    99+
    2022-10-19
  • 基于log4j2.properties踩坑与填坑的示例分析
    这篇文章主要介绍基于log4j2.properties踩坑与填坑的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!log4j2.properties踩坑与填坑日志配置门面模式:slf4j日志库:log4j2引入...
    99+
    2023-06-22
  • Canvas跨域脱坑的示例分析
    小编给大家分享一下Canvas跨域脱坑的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!先来看下实现方法。实现方法目标图片一般是由 图片 + 文本 构成。无...
    99+
    2023-06-09
  • Python 3.x踩坑的示例分析
    这篇文章主要为大家展示了“Python 3.x踩坑的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Python 3.x踩坑的示例分析”这篇文章吧。处处有坑1. 文件读...
    99+
    2023-06-29
  • mybatis-plus QueryWrapper排序的坑案例分析
    这篇文章主要介绍了mybatis-plus QueryWrapper排序的坑案例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇mybatis-plus QueryWrapper排序的坑案...
    99+
    2023-06-29
  • SpringMVC配置404踩坑的示例分析
    这篇文章给大家分享的是有关SpringMVC配置404踩坑的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。错误错误就是一直报404,也就说找不到路径。怎么试路径还是404。我相信大家也是非常讨厌404的吧...
    99+
    2023-06-29
  • vue2使用swiper4踩坑的示例分析
    vue2使用swiper4踩坑的示例分析,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。前言一开始打算采用最新的swiper7,后来好像是vue2兼容性问题,各种报错,所以从...
    99+
    2023-06-26
  • vue3 pinia踩坑及解决实例代码分析
    本篇内容主要讲解“vue3 pinia踩坑及解决实例代码分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“vue3 pinia踩坑及解决实例代码分析”吧!安装yarn&nbs...
    99+
    2023-07-05
  • Linux高并发踩过的坑及性能实例分析
    这篇文章主要讲解了“Linux高并发踩过的坑及性能实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux高并发踩过的坑及性能实例分析”吧!前言Linux操作系统是现在服务器的首选操...
    99+
    2023-06-22
  • 实例分析nodejs模块xml2js解析xml过程中遇到的坑
    本文实例讲述了nodejs模块xml2js解析xml过程中遇到的坑。分享给大家供大家参考,具体如下: 在一个项目中,用到nodejs模块xml2js解析xml,xml的数据如下: <xml>...
    99+
    2022-06-04
    过程中 实例 模块
  • springboot单元测试依赖踩坑实例源码分析
    本文小编为大家详细介绍“springboot单元测试依赖踩坑实例源码分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“springboot单元测试依赖踩坑实例源码分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧...
    99+
    2023-07-05
  • 分享一个mongodb和golang搭伙采坑的示例分析
    这篇文章主要介绍了分享一个mongodb和golang搭伙采坑的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。什么是golanggolang 是Google开发的一种...
    99+
    2023-06-14
  • golang fasthttp的踩坑分析
    这篇文章主要讲解了“golang fasthttp的踩坑分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“golang fasthttp的踩坑分析”吧!一个简单的系统,结构如下:我们的服务A...
    99+
    2023-06-25
  • Vue微信公众号开发踩坑的示例分析
    这篇文章将为大家详细讲解有关Vue微信公众号开发踩坑的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。需求微信授权登录(基于公众号的登录方案)接入JS-SDK实现图...
    99+
    2022-10-19
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作