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 ...
随机推荐
- Laravel5.4框架中视图共享数据的方法详解
本文实例讲述了Laravel5.4框架中视图共享数据的方法.分享给大家供大家参考,具体如下: 每个人都会遇到这种情况:某些数据还在每个页面进行使用,比如用户信息,或者菜单数据,最基本的做法是在每个视图 ...
- 26、pathlib文件系统模块(了解)
一.pathlib库官方定义 pathlib 是Python内置库,Python 文档给它的定义是 Object-oriented filesystem paths(面向对象的文件系统路径).path ...
- 使用VSCode开发Flutter
前言 为什么使用VSCode? flutter官方推荐的编辑器有IDEA/Android Studio和VSCode, 之前开发Flutter用的IDEA, 不过IDEA始终比较重,于是换用VSCod ...
- Docker报错“Dockerfile parse error line 1: FROM requires either one or three arguments”
看官方文档Format: 以 '#' 开头一行被视为评论,出现在其他位置视为参数. 也就不难理解报错原因:将写在同一行的注释视为参数了. 原Dockerfile: 改为:
- Java验证jwt token
https://jwt.io/ RS256加密JWT生成.验证 https://blog.csdn.net/u011411069/article/details/79966226 How to loa ...
- Linux安全加固(二)禁止普通用户su到root/设置SSH终端接入白名单/修改history条数
一.禁止普通用户su到root管理员.设置可以su到root的白名单 1.首先看一下正常情况 2.可以看到普通用户使用su root命令,输入密码即可登录到root用户 3.下面开始配置禁止所有普通用 ...
- 信息学奥赛一本通 提高篇 序列第k个数 及 快速幂
我是传送门 这个题首先是先判断是等差还是等比数列 等差的话非常简单: 前后两个数是等差的,举个栗子: 3 6 9 12 这几个数,(我感觉 1 2 3 4并说明不了什么) 每次都加3嘛,很容易看出,第 ...
- dateTime格式转换
select Convert(varchar(8),GETDATE(),112) Select replace(CONVERT(varchar(8), GETDATE(), 108),':','')
- Java编程思想之七复用类
复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对之加以改变是不够的,它还必须做更多的事情. 使用类而不破坏程序代码: 在新类中产生现有对象.由于新的类是由现有 ...
- 响应: 500 OOPS: vsftpd: refusing to run with writable root inside chroot()
原vsftpd服务器的系统从centos6.8升级到centos7.2.vsftpd使用yum方式安装,用户采用系统用户登录.由于系统升级到centos7,yum安装的vsftpd版本改变.因此按ce ...