java8中parallelStream提升数倍查询效率是怎样实现的,来看看这篇文章

作者:我恰芙蓉王
原文:https://www.cnblogs.com/-tang/p/13283216.html
业务场景
在很多项目中,都有类似数据汇总的业务场景,查询今日注册会员数,在线会员数,订单总金额,支出总金额等。。。这些业务通常都不是存在同一张表中,我们需要依次查询出来然后封装成所需要的对象返回给前端。那么在此过程中,就可以把这个接口中“大任务”拆分成N个小任务,异步执行这些小任务,等到最后一个小任务执行完,把所有任务的执行结果封装到返回结果中,统一返回到前端展示。
同步执行
首先看看同步执行的代码
public class Test {
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
class Result {
/**
* 在线人数
*/
Integer onlineUser;
/**
* 注册人数
*/
Integer registered;
/**
* 订单总额
*/
BigDecimal orderAmount;
/**
* 支出总额
*/
BigDecimal outlayAmount;
}
@org.junit.Test
public void collect() {
System.out.println("数据汇总开始");
long startTime = System.currentTimeMillis();
Integer onlineUser = queryOnlineUser();
Integer registered = queryRegistered();
BigDecimal orderAmount = queryOrderAmount();
BigDecimal outlayAmount = queryOutlayAmount();
Result result = new Result(onlineUser, registered, orderAmount, outlayAmount);
long endTime = System.currentTimeMillis();
System.out.println("获取汇总数据结束,result = " + result);
System.out.println("总耗时 = " + (endTime - startTime) + "毫秒");
}
public Integer queryOnlineUser() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("查询在线人数 耗时2秒");
return 10;
}
public Integer queryRegistered() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("查询注册人数 耗时2秒");
return 10086;
}
public BigDecimal queryOrderAmount() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("查询订单总额 耗时3秒");
return BigDecimal.valueOf(2000);
}
public BigDecimal queryOutlayAmount() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("查询支出总额 耗时3秒");
return BigDecimal.valueOf(1000);
}
}
执行时长想必大家都能够想得到,理所应当是10秒以上
数据汇总开始
查询在线人数 耗时2秒
查询注册人数 耗时2秒
查询订单总额 耗时3秒
查询支出总额 耗时3秒
获取汇总数据结束,result = Test.Result(onlineUser=10, registered=10086, orderAmount=2000, outlayAmount=1000)
总耗时 = 10008毫秒
异步执行
下面换成异步执行,用java8的parallelStream(并行流),这里为什么不用Thread呢,这里有一个注意点,我们需要获取所有所有子任务执行完的时间点,在这个时间点之后才能将结果封装返回,Thread没有办法满足,这里parallelStream和函数式接口就登场了。
java8的特性之一 —— lambda表达式,就是配合函数式接口使用的。
java8内置了四大核心函数式接口:
1、Consumer : 消费型接口 void accept(T t);
2、Supplier : 供给型接口 T get();
3、Function<T,R> : 函数型接口 R apply(T t);
4、Predicate : 断言型接口 boolean test(T t);
这四大核心函数式接口其下还有很多子接口,基本上能满足日常项目所用,这里扯远了。。 直接上代码。
这里我们需要使用的是Runable接口,是无参无返回值的一个接口。在实际场景中,可能有时间范围之类的查询参数的,则可以根据不同业务使用不同的接口。这种方式也可以用Future接口去实现,有兴趣的可以试一试,这里就不多做叙述了。
@org.junit.Test
public void collect() {
System.out.println("数据汇总开始");
long startTime = System.currentTimeMillis();
Result result = new Result();
List<Runnable> taskList = new ArrayList<Runnable>() {
{
add(() -> result.setOnlineUser(queryOnlineUser()));
add(() -> result.setRegistered(queryRegistered()));
add(() -> result.setOrderAmount(queryOrderAmount()));
add(() -> result.setOutlayAmount(queryOutlayAmount()));
}
};
taskList.parallelStream().forEach(v -> v.run());
long endTime = System.currentTimeMillis();
System.out.println("获取汇总数据结束,result = " + result);
System.out.println("总耗时 = " + (endTime - startTime) + "毫秒");
}
执行结果,由于四个子任务都是并行的,效率直接提升了三倍,如果子任务越多的话提升效果越明显。
数据汇总开始
查询在线人数 耗时2秒
查询注册人数 耗时2秒
查询订单总额 耗时3秒
查询支出总额 耗时3秒
获取汇总数据结束,result = Test.Result(onlineUser=10, registered=10086, orderAmount=2000, outlayAmount=1000)
总耗时 = 3079毫秒
总结
1.parallelStream是异步编程的好帮手,在使用过程中一定要注意线程安全的问题。
2.以上这种方式只能用在没有事务的业务中,因为在多线程中,事务是不共享的。
最后
私信回复 资料 领取一线大厂Java面试题总结+
阿里巴巴泰山手册+各知识点学习思维导+一份300页pdf文档的Java核心知识点总结!
这些资料的内容都是面试时面试官必问的知识点,篇章包括了很多知识点,其中包括了有基础知识、Java集合、JVM、多线程并发、spring原理、微服务、Netty 与RPC 、Kafka、日记、设计模式、Java算法、数据库、Zookeeper、分布式缓存、数据结构等等。

java8中parallelStream提升数倍查询效率是怎样实现的,来看看这篇文章的更多相关文章
- java8的parallelStream提升数倍查询效率
业务场景 在很多项目中,都有类似数据汇总的业务场景,查询今日注册会员数,在线会员数,订单总金额,支出总金额等...这些业务通常都不是存在同一张表中,我们需要依次查询出来然后封装成所需要的对象返回给前端 ...
- 分布式协同AI基准测试项目Ianvs:工业场景提升5倍研发效率
摘要:全场景可扩展的分布式协同AI基准测试项目 Ianvs(雅努斯),能为算法及服务开发者提供全面开发套件支持,以研发.衡量和优化分布式协同AI系统. 本文分享自华为云社区<KubeEdge|分 ...
- MySQL 5.7 优化SQL提升100倍执行效率的深度思考(GO)
系统环境:微软云Linux DS12系列.Centos6.5 .MySQL 5.7.10.生产环境,step1,step2是案例,精彩的剖析部分在step3,step4. 1.慢sql语句大概需要13 ...
- mysql中存储字段类型的查询效率
检索性能从快到慢的是(此处是听人说的): 第一:tinyint,smallint,mediumint,int,bigint第二:char,varchar第三:NULL 解释(转载): 整数类型1.TI ...
- atitit.提升2--3倍开发效率--cbb体系的建设..
atitit.提升开发效率--cbb体系的建设.. #--提升倍数,大概2--3倍.. #---cbb的内容 知识的,expt的,经验的技术的部件的问题库的角度.. #---cbb的层次,tech l ...
- 可以提升3倍开发效率的 Intellij IDEA快捷键大全汇总(2019)
整理了一下IDEA的常用快捷键,可以打印出来或者弄成图片设置为桌面,为广大的程序员们节省更多的时间去谈恋爱. 常用快捷键1 Ctrl+Shift + Enter,语句完成 “!”,否定完成,输入表达式 ...
- 阿里云SaaS加速器“宜搭”发布宜搭Plus提升6倍研发效率
9月26日,在杭州云栖大会上,阿里云SaaS加速器的“底座”——“宜搭”正式发布“宜搭Plus”低代码开发平台.开发复杂企业业务系统所需要的领域数据模型.逻辑&服务编排.专业UI页面设计等,都 ...
- union all 取代 select中的case when 提高查询效率
首先union all不是适用于所有情况,其次,case when的可读性肯定要强.所以在不是特别在意性能的情况下, 可以考虑用case when. 再者,不是所有情况下的union all都要比ca ...
- Java7与Java8中的HashMap和ConcurrentHashMap知识点总结
JAVA7 Java7的ConcurrentHashMap里有多把锁,每一把锁用于其中一部分数据,那么当多线程访问容器里不同数据段的数据时,线程间就不会存在锁竞争,从而可以有效的提高并发访问效率呢.这 ...
随机推荐
- Unity常见的三种数据本地持久化方案
做游戏的时候常常会有数据配置或者存读档的需求,本文整理了常用的几种解决方案,分别是Unity自带的PlayerPrefs类,XML文件和Json文件. 一. PlayerPrefs 这是Unity自带 ...
- Python基础语法一
所有内容都在代码上,有相关代码注释 # #代表注释 # 区分大小写.以回车换行结束 # 多行编写可以使用反斜杠 \ # 缩进代表一个代码块 #数值 #int类型可以使用下划线分割 c=123_456_ ...
- .Net: C#中的委托(Delegate)和事件(Event)
委托和事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真 是太容易了,而没有过去的人每次 ...
- Nuxt+Express后端api接口配置与实现方式
Nuxt.js 是一个基于 Vue.js 的轻量级应用框架,可用来创建服务端渲染 (SSR) 应用.本文带你了解在 Nuxt.js 中使用 Express 如何编写实现后端的 api 接口. 创建接口 ...
- HTTP 协议详解(二)
前面一篇已经说过了 HTTP 的基本特性,HTTP 的发展史,前情回顾.这一篇就更详细的 HTTP 协议使用过程一些参数配置,缓存,Cookie设置相关的细节做一些梳理. 数据类型与编码 在 TCP/ ...
- 一个很酷炫也挺实用的JS库leader-line
简单粗暴,直入主题,看看效果再说. 是不是这效果挺棒?这样的效果在做系统时,可以有很多的应用,可以让枯燥的页面生动起来. 具体效果,大家可以上这个搜索网站Mag[i]上面看,切身体会一下. 这是一个开 ...
- 使用phpQuery进行采集数据,模拟curl提升访问速度
使用php采集网页数据一般有多种方法,有时候会使用正则去采集页面,但是当我们需要采集的页面大并且多的话,会严重的浪费我们的cpu,这时候我们可以使用phpQuer来进行采集,不知道phpQuery的童 ...
- (私人收藏)java实例、知识点、面试题、SHH、Spring、算法、图书管理系统、综合参考
https://pan.baidu.com/s/1hkmgJU6pf2sBjNV1NlOaNgr6l2 Java趣味编程100例java经典选择题100例及答案java面试题大全java排序算法大全j ...
- git bash中提示 bash:node: command not found
昨天小伙伴私信,git bash以及windows 的cmd命令行下均无法运行node npm. 究其原因是环境变量的问题.解决步骤: 1>在"此电脑"中右击,选择" ...
- Linux高并发网络编程开发——10-Linux系统编程-第10天(网络编程基础-socket)
在学习Linux高并发网络编程开发总结了笔记,并分享出来.有问题请及时联系博主:Alliswell_WP,转载请注明出处. 10-Linux系统编程-第10天(网络编程基础-socket) 在学习Li ...