车驰夜幕|面试官:java8中parallelStream提升数倍查询效率是怎样实现的

业务场景在很多项目中 , 都有类似数据汇总的业务场景 , 查询今日注册会员数 , 在线会员数 , 订单总金额 , 支出总金额等 。。。 这些业务通常都不是存在同一张表中 , 我们需要依次查询出来然后封装成所需要的对象返回给前端 。 那么在此过程中 , 就可以把这个接口中“大任务”拆分成N个小任务 , 异步执行这些小任务 , 等到最后一个小任务执行完 , 把所有任务的执行结果封装到返回结果中 , 统一返回到前端展示 。
车驰夜幕|面试官:java8中parallelStream提升数倍查询效率是怎样实现的同步执行首先看看同步执行的代码
public class Test {@Data@NoArgsConstructor@AllArgsConstructor@ToStringclass Result {/*** 在线人数*/Integer onlineUser;/*** 注册人数*/Integer registered;/*** 订单总额*/BigDecimal orderAmount;/*** 支出总额*/BigDecimal outlayAmount;}@org.junit.Testpublic 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提升数倍查询效率是怎样实现的异步执行下面换成异步执行 , 用java8的parallelStream(并行流) , 这里为什么不用Thread呢 , 这里有一个注意点 , 我们需要获取所有所有子任务执行完的时间点 , 在这个时间点之后才能将结果封装返回 , Thread没有办法满足 , 这里parallelStream和函数式接口就登场了 。
java8的特性之一 —— lambda表达式 , 就是配合函数式接口使用的 。
java8内置了四大核心函数式接口:
1、Consumer : 消费型接口 void accept(T t);
【车驰夜幕|面试官:java8中parallelStream提升数倍查询效率是怎样实现的】2、Supplier : 供给型接口 T get();
3、Function : 函数型接口 R apply(T t);