Java 8并行流的性能陷阱
并行化流被分成多个块,每个块独立处理,结果在最后汇总。
CPU密集型代码如下:
private long countPrimes(int max) {
|
countPrimes 计算1到最大值之间的素数的数量。数字流由range方法创建,切换到并行模式,过滤掉非素数,剩余的计算总数。由于isPrime 方法极其无效且占用大量CPU,我们可以利用并行化并利用所有可用的CPU内核。
我们来看另一个例子:
private List<StockInfo> getStockInfo(Stream<String> symbols) {
|
输入是一个股票代码列表,我们必须调用慢速网络操作来获取有关股票的一些细节。在这里,我们不处理CPU密集型操作,但我们也可以利用并行化。并行执行多个网络请求是个好主意。同样,并行流的一个很好的任务,你同意吗?
如果您这样做,请再次查看上一个示例。有一个很大的错误。你看到了吗?问题是所有并行流都使用公共fork-join线程池。如果提交长时间运行的任务,则会有效地阻塞池中的所有线程。因此,您将阻塞使用并行流的所有其他任务。
想象一下servlet环境,当一个请求调用时getStockInfo() ,另一个请求调用 countPrimes()。即使每个都需要不同的资源,也会阻止另一个。更糟糕的是,你不能为并行流指定线程池; 整个类加载器必须使用相同的。
让我们在下面的例子中说明它:
private void run() throws InterruptedException {
|
在这里,我们模拟系统中的六个线程。所有这些都在执行CPU密集型任务,第一个被“暂停”,在它找到素数后就睡了一秒钟。这只是一个人为的例子; 你可以想象一个被卡住或执行阻塞操作的线程。
问题是:执行此代码时会发生什么?我们有六个任务; 其中一个将需要一整天才能完成,其余的应该更快完成。毫不奇怪,每次执行代码时,都会得到不同的结果。你想在生产系统中有这样的行为吗?一个杜塞的任务取消了应用程序的其余部分?我猜不会。
关于如何确保永远不会发生这样的事情,只有两种选择。第一个是确保提交到公共fork-join池的所有任务都不会卡,必须在合理的时间内完成。但这说起来容易做起来难,尤其是在复杂的应用程序中。
另一种选择是不使用并行流,并等到Oracle允许我们指定用于并行流的线程池。
Java 8并行流的性能陷阱的更多相关文章
- RecursiveTask和RecursiveAction的使用 以及java 8 并行流和顺序流(转)
什么是Fork/Join框架 Fork/Join框架是Java7提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架. 我 ...
- JAVA使用并行流(ParallelStream)时要注意的一些问题
https://blog.csdn.net/xuxiaoyinliu/article/details/73040808
- java 8新特性 并行流
使用并行流,提高cpu利用率,提高运算速度 /** * java 8并行流 * 底层运用fork join框架 */ @Test public void test(){ Instant start = ...
- Java 8 (6) Stream 流 - 并行数据处理与性能
在Java 7之前,并行处理集合非常麻烦.首先你要明确的把包含数据的数据结构分成若干子部分,然后你要把每个子部分分配一个独立的线程.然后,你需要在恰当的时候对他们进行同步来避免竞争,等待所有线程完成. ...
- 《Java 8 in Action》Chapter 7:并行数据处理与性能
在Java 7之前,并行处理数据集合非常麻烦.第一,你得明确地把包含数据的数据结构分成若干子部分.第二,你要给每个子部分分配一个独立的线程.第三,你需要在恰当的时候对它们进行同步来避免不希望出现的竞争 ...
- java8学习之自定义收集器深度剖析与并行流陷阱
自定义收集器深度剖析: 在上次[http://www.cnblogs.com/webor2006/p/8342427.html]中咱们自定义了一个收集器,这对如何使用收集器Collector是极有帮助 ...
- Java8新特性 并行流与串行流 Fork Join
并行流就是把一个内容分成多个数据块,并用不同的线程分 别处理每个数据块的流. Java 8 中将并行进行了优化,我们可以很容易的对数据进行并 行操作. Stream API 可以声明性地通过 para ...
- JAVA8给我带了什么——并行流和接口新功能
流,确定是笔者内心很向往的天堂,有他之后JAVA在处理数据就变更加的灵动.加上lambda表达不喜欢都不行.JAVA8也为流在提供另一个功能——并行流.即是有并行流,那么是不是也有顺序流.没有错.我前 ...
- list.stream().parallel() 并行流
https://blog.csdn.net/u011001723/article/details/52794455/ : parallel()其实就是一个并行执行的流.它通过默认的ForkJoin ...
随机推荐
- Zipkin 的 Docker 镜像使用
1.Zipkin 在 dockerhub 上网址:https://hub.docker.com/r/openzipkin/zipkin 2.下载镜像 docker pull openzipkin/zi ...
- Java Excel 导入导出(一)
本文主要描述通过java实现Excel导入导出 一.读写Excel三种常用方式 1.JXL——Java Excel开放源码项目:读取,创建,更新 2.POI——Apache POI ,提供API给Ja ...
- Spring启动,constructor,@PostConstruct,afterPropertiesSet,onApplicationEvent执行顺序
package com.xx; import javax.annotation.PostConstruct; import javax.annotation.Resource; import org. ...
- PHP 判断时间段 至今过了多长时间
/** * * @param timestamp $time 输入时间 * @return str $str 输入时间与现在时间差的中文 */ function wordTime($time) { / ...
- Presto Infrastructure at Lyft
转载一篇关于 lyft presto 平台建设的实践 Overview Early in 2017 we started exploring Presto for OLAP use cases and ...
- Incorrect string value: 'è·å...' for column 'result' at row 1
错误详情信息: ### Error updating database. Cause: java.sql.SQLException: Incorrect ### The error may invol ...
- 《JAVA程序设计》_第十一周学习总结
一.学习内容 13.1 URL类 URL类是java.net包中的一个重要的类,URL的实例封装着一个统一资源定位符,使用URL创建对象的应用程序称作客户端程序. 一个URL对象包含的三个基本信息:协 ...
- js控制网页窗口一打开就自动全屏
1.如果不需要开新窗口 在body区加入: <body onLoad= "javascript:window.resizeTo(screen.availWidth,screen.a ...
- vs2010怎么更改调试时使用的浏览器
在当前网站的起始网页上右击,在右击菜单中选择 浏览方式 步骤阅读 2
- Java编程思想之六访问权限控制
访问控制(或隐藏具体实现)与"最初的实现并不恰当"有关. 访问权限控制的等级,从最大权限到最小权限依次为:public,protected,包访问权限(没有关键字)和private ...