adobe stream的最后一行空行_玩转Java8Stream(五、并行Stream)
java8的并行Stream对开发者非常友好,非常容易实现并行计算。并行Stream底层使用ForkJoinTask实现Stream的并行处理,充分利用cpu的多核能力,Stream的API将底层复杂实现完全屏蔽了,开发者仅需调用一个方法即可实现并行计算,就是这么简单。
开启并行Stream
开启并行Stream只需在调用终止操作符之前调用parallel()方法即可开启并行计算。
@Test public void parallelStream(){ IntStream.range(0,100) .parallel() .forEach(e-> System.out.println(Thread.currentThread()+" "+e)); }
执行上述代码,可以看出代码将会交由ForkJoinPool中的线程执行。
小试牛刀
这里使用分别使用并行Stream和穿行Stream计算0到100000000000之间的和
@Test public void testSum(){ //并行计算 long time= System.currentTimeMillis(); long sum1 = LongStream.rangeClosed(1,100000000000l).parallel().sum(); System.out.println(System.currentTimeMillis()-time); //串行计算 time = System.currentTimeMillis(); long sum2 = LongStream.rangeClosed(1,100000000000l).sum(); System.out.println(System.currentTimeMillis()-time); System.out.println("sum1 = "+sum1+" sum2 = "+sum2); Assert.assertTrue(sum1==sum2); }
执行结果如图,我的cpu是6核的,串行计算的时间差不多是并行计算的5倍;并行计算下充分利用了cpu的多核性能,如果数据量更大,两者之间的差距更大,并行Stream的优势更加明显。
sequential()和parallel()
默认情况下创建的stream都是串行的,parallel将串行流转成并行流,两者是互斥冲突的,sequential将并行流转成串行流,但并不意味者二者不可同时出现。
isParallel()可以检测stream是否为并行stream。
@Test public void isParallel(){ IntStream stream = IntStream.range(0,100); stream.parallel(); Assert.assertTrue(stream.isParallel()); }
如代码所示,执行‘串行->并行->串行->并行’的转换,最终还是并行流。
@Test public void spspIsP(){ IntStream stream = IntStream.range(0,100); stream.parallel().map(e->e<<1).sequential().parallel(); Assert.assertTrue(stream.isParallel()); }
如代码所示,执行‘串行->并行->串行’的转换,最终还是串行流。
@Test public void spsIsS(){ IntStream stream = IntStream.range(0,100); stream.parallel().map(e->e<<1).sequential(); Assert.assertFalse(stream.isParallel()); }
上例子说明,流的串行和并行取决于最后调用的那个方法(sequential() or parallel())。
ForkJoinPool
并行stream底层依赖于ForkJoinPool.commonPool线程池,这是一个jvm进程全局共享的线程,当这个线程池中执行了耗时操作,后面的任务将会堆积,造成性能问题;默认情况下这个线程池的大小为逻辑核数-1,当然你也可以通过jvm参数‘java.util.concurrent.ForkJoinPool.common.parallelism’来修改线程的池大小,这里并不建议使用这种方式,最好的方式是使用自定义的线程池。
如代码所示,创建4线程的ForkJoinPool线程池。
@Test public void CustomPool(){ ForkJoinPool forkJoinPool = new ForkJoinPool(4); forkJoinPool.submit(()->{ IntStream.range(0,100).parallel().forEach(e-> System.out.println(Thread.currentThread()+" "+e)); }).join(); }
代码执行结果如图,并行的stream在自定义的线程池中执行。
那为什么forkJoinPool.submit()就可以实现自定义线程池呢?查看源码得知,ForkJoinWorkerThread内部会持有ForkJoinPool的引用,在代码执行时,最终会调用doInvoke方法,通过Thread.currentThread可以知道是ForkJoinWorkerThread类型的线程,进而获取到ForkJoinPool,最终利用这个pool来执行计算。
/** * Implementation for invoke, quietlyInvoke. * * @return status upon completion */ private int doInvoke() { int s; Thread t; ForkJoinWorkerThread wt; return (s = doExec()) < 0 ? s : ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) ? (wt = (ForkJoinWorkerThread)t).pool. awaitJoin(wt.workQueue, this, 0L) : externalAwaitDone(); }
总结
并行Stream给开发者带来了极大的便利,一行代码即可开启多线程并行计算,excellent!但是并行计算也要在一定条件下才能使用,比如任务之间不能有依赖、不能存在竞态条件等。
adobe stream的最后一行空行_玩转Java8Stream(五、并行Stream)相关推荐
- adobe stream的最后一行空行_Excel VBA 7.66 如何快速删除数据间空行?手动慢又乱!VBA快又准...
前景提要(文末提供源码下载) 其实不管是做数据处理还是数据分析,都并不算是很困难的事情,只要数据标准,分析出我们想要的结果那也是分分钟的事情,就算是数据大点,我多花点时间也能得到我们想要的结果,怕就怕 ...
- 5单个编译总会编译全部_玩转Android10(五)源码编译开发中常用命令
源码开发编译中,熟练掌握常用命令,可以提高开发工作效率.Android源码中,将相关的命令分为如下几类: 1.初始化源码编译环境 初始化编译环境,为后续提供如lunch.make.xxgrep.god ...
- Python 解决写入csv中间隔一行空行问题
转载解决写入csv中间隔一行空行问题 写入csv: with open(birth_weight_file,'w') as f:writer=csv.writer(f)writer.writerow( ...
- body标签下莫名奇妙多了一行空行,原来是编码的问题
之前为了方便,直接在服务器修改文件,然后点保存,但是问题来了,在顶部莫名奇妙多了一个空行,如图1 图1 原来在源代码编辑的代码如图2 图2 但是在FF或者Chrome外部样式却在body里面,而不是h ...
- 玩转Java8中的 Stream 之从零认识 Stream
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:litesky www.jianshu.com/p/11c9 ...
- java stream 取不同的数据_基础篇:JAVA.Stream函数,优雅的数据流操作
前言 平时操作集合数据,我们一般都是for或者iterator去遍历,不是很好看.java提供了Stream的概念,它可以让我们把集合数据当做一个个元素在处理,并且提供多线程模式 流的创建 流的各种数 ...
- Java8 Stream:20+实际例子,玩转集合的筛选、归约、分组、聚合
来源: https://blog.csdn.net/mu_wind/article/details/109516995 Java8中的stream,可大幅提升咱们的开发效率,带大家看下stream到底 ...
- 玩知乎五年,我赚了多少钱?
大家好,我是张小方.小方是一位知乎老鸟,玩了快五年知乎,上个月知乎粉丝终于突破一万了,惊喜得我不知所措呀. 不止一个读者在问我:小方老师现在也是知乎万粉大 V 了,知乎如此多的关注.点赞,加上付费咨询 ...
- 解决 HTTP/2 stream 1 was not closed cleanly before end of the underlying stream
使用 git 的时候发现一直提示 HTTP/2 stream 1 was not closed cleanly before end of the underlying stream. 通过排查发现, ...
最新文章
- 给char*一个名份
- C# 图片识别(支持21种语言)
- Java讲课笔记05:运算符与表达式
- 一次 Java 内存泄漏排查过程,涨姿势
- Runloop与autoreleasePool联系
- 推荐几个前端模板下载站
- YYText-swift,swift版的YYText,优化了yylabel和yytextview的部分扩展
- 计算机电脑配置ppt,计算机应用基础之word2010课件.ppt
- 金融学习之四——插值法求远期国债收益率
- html语言加号点一下变成减号6,CSS3 linear-gradient线性渐变生成加号和减号的方法...
- nisp和cisp证书有什么区别
- Java多线程探究-死锁原因
- 信奥学习规划 信息学竞赛之路(2022.07.31)
- ndarray数组的操作和运算
- 华为认证--云计算HCIA-2
- 北京大学计算机学院,官宣首任院长
- 【弄nèng - Activiti6】Activiti6入门篇(十六)—— 信号中间事件
- MT5 EA交易期货-市价单开仓平仓
- 常用网络安全问题排查命令总结
- Android消息推送叨逼叨
热门文章
- Java快速开发框架LML简介
- 使用 IAsyncResult 进行 .NET 异步编程
- 吐血原创-我用“电驴”抓肉鸡!!!
- html 方式使用iview,VUE之iview框架使用教程
- mysql建立索引 有什么缺陷_MySQL数据库建立索引的优缺点以及什么样的字段适合建立索引...
- ajax提交前先验证,jQuery验证AJAX之前提交(jQuery validation before AJAX sub
- 信息学奥赛一本通(1094:与7无关的数)
- 信息学奥赛一本通(1054:三角形判断)
- 38 SD配置-销售凭证设置-定义拒绝原因
- 37 CO配置-控制-产品成本控制-成本对象控制-实际成本核算/物料分类帐-分配货币类型并定义物料分类账类型