Java8 中的ParallelStream
作者:onlythinking 发布时间:2022-09-07 19:00:23
目录
1、Stream API
2、ParallelStreams执行原理
3、ParallelStreams注意事项
前言:
并行编程势不可挡,Java从1.7开始就提供了Fork/Join 支持并行处理。java1.8 进一步加强。
并行处理就是将任务拆分子任务,分发给多个处理器同时处理,之后合并。
1、Stream API
Java 8 引入了许多特性,Stream API
是其中重要的一部分。区别 InputStream OutputStream
,Stream API
是处理对象流而不是字节流。
执行原理如下,流分串行和并行两种执行方式
// 串行执行流
stream().filter(e -> e > 10).count();
// 并行执行流
.parallelStream().filter(e -> e > 10).count()
2、ParallelStreams执行原理
并行执行时,java
将流划分为多个子流,分散在不同CPU并行处理,然后进行合并。
并行一定比串行更快吗?这不一定,取决于两方面条件:
处理器核心数量,并行处理核心数越多自然处理效率会更高。
处理的数据量越大,优势越强。这也很好理解,比如十个人干一个人就能完成的活儿会比它自己干更便宜?
3、ParallelStreams注意事项
使用并行流时,不要使用collectors.groupingBy,collectors.toMap
,替代为
collectors.groupingByConcurrent , collectors.toConcurrentMap
,或直接使用串行流。
原因,并行流执行时,通过操作Key来合并多个map的操作比较昂贵。详细大家可以查看官网介绍。
https://docs.oracle.com/javase/tutorial/collections/streams/parallelism.html#concurrent_reduction
Map<String, List<Person>> byGender =
roster
.stream()
.collect(Collectors.groupingBy(Person::getGender));
ConcurrentMap<String, List<Person>> byGender =
roster
.parallelStream()
.collect(Collectors.groupingByConcurrent(Person::getGender));
ParallelStreams
默认使用 ForkJoinPool.commonPool()
线程池。
注意:默认情况下,你写的 ParallelStreams 都是通过该线程池调度执行,整个应用程序都共享这个线程池。
看一个例子,我们查询一批新闻数据,可以利用并行化来处理远程新闻下载。
public List<News> queryNews(Stream<String> ids) {
return ids.parallel()
.map(this::getNews) // 网络操作,新闻下载
.collect(toList());
}
因为是网络操作,存在很多不确定性,假如某个任务运行时间较长,导致线程池资源占据,阻塞其它线程,这样就阻止了其他的并行流任务正常进行。
如果解决这个问题的其中一种方式,进行线程池隔离
。那么如何自定义并行流的线程池呢?
ForkJoinPool
构造参数我们默认设置为CPU核心数。
ForkJoinPool customThreadPool = new ForkJoinPool(4);
long actualTotal = customThreadPool
.submit(() -> roster.parallelStream().reduce(0, Integer::sum)).get();
总结:
Java 1.8
提供的Stream API
简化了代码,很好用。不过在使用过程中应该注意以上问题。
来源:https://www.onlythinking.com/2020/06/05/%E4%BD%A0%E5%9C%A8%E4%BD%BF%E7%94%A8java-8-parallel-streams-%E5%90%97%EF%BC%9F/
![](https://www.aspxhome.com/images/zang.png)
![](https://www.aspxhome.com/images/jiucuo.png)
猜你喜欢
- 前言今天刷个题,遇到一个很有趣的问题,关于Comparator的使用,感觉也是一个关于写代码的一些小细节的问题关于ComparatorCom
- 因为mybatis好使,所以几乎需要操作数据库的时候,我都会使用mybatis,而且在一个正式的项目中,同时存在BS和CS的程序,都使用的M
- 前言上一节我们说到从HttpWebHandlerAdapter的handle方法说起到DispatcherHandler的调用流程那么Htt
- a)原理:每一趟从待排序的记录中选出最小的元素,顺序放在已排好序的序列最后,直到全部记录排序完毕。也就是:每一趟在n-i+1(i=1,2,…
- spring security用了也有一段时间了,弄过异步和多数据源登录,也看过一点源码,最近弄rest,然后顺便搭oauth2,前端用js
- 此例子,用于说明如何在Java中对“注解 Annotation”的定义、使用和解析的操作。注解一般用于自定义开发框架中,至于为什么使用,此处
- 前言最近做一个微信公众号服务,有一些简单的图片处理功能。主要就是用户在页面操作,前端做一些立刻显示的效果,然后提交保存时后端真正修改原图。从
- Java 8中引入了CompletableFuture类,它是一种方便的异步编程工具,可以处理各种异步操作,如网络请求、文件IO和数据库操作
- 目录引言配置yml文件创建数据源配置类为每个数据库创建配置类引言今天为大家带来一些非常有用的实战技巧,比如在我们需要对两个数据库进行操作的时
- thymeleaf介绍简单说, Thymeleaf 是一个跟 Velocity、FreeMarker 类似的模板引擎,它可以完全替代 JSP
- 谷歌官方推出了一种侧滑菜单的实现方式(抽屉效果),即 DrawerLayout,这个类是在Support Library里的,需要加上and
- 1、前言随着技术的发展,微信的一系列服务渗透进了我们的生活,但是我们应该怎样进行微信方面的开发呢。相信很多的小伙伴们都很渴望知道吧。这篇文章
- 一、先看下项目结构CodeGenerator:生成器主类resources下的mapper.java.vm:一个模板类,用以在生成dao层时
- 前言当你编写一个应用时,你通常都会希望用户能够定制化他们和应用交互的方式,以及应用与系统进行交互的方式。这种方式通常被称为 &ldq
- 前言众所周知,encache是现在最流行的java开源缓存框架,配置简单,结构清晰,功能强大。通过注解 @Cacheable 可以快速添加方
- 本文实例讲述了C#实现的xml操作类,分享给大家供大家参考,具体如下:using System;using System.Data;usin
- 本文实例讲述了C#实现类似新浪微博长URL转短地址的方法。分享给大家供大家参考。具体如下:一、前台判断用户输入URL的JS代码如下。func
- 在程序中封装了一个List集合对象,然后需要把该集合中的实体插入到数据库中,由于项目使用了Spring+MyBatis的配置,所以打算使用M
- Spring Cloud 为开发人员提供了一系列的工具来快速构建分布式系统的通用模型 。例如:配置管理、服务发现、断路由、智能路由、微代理、
- 概述日常工作中,我们经常会有发送 HTTP 网络请求的需求,概括下我们常见的发送 HTTP 请求的需求内容:可以发送基本的 GET/POST