我恰芙蓉王资料

本文主要介绍我恰芙蓉王资料 方法和在新技术下所面对的“挑战”,方便大家深入理解我恰芙蓉王资料 过程。本文也将分享我恰芙蓉王资料 所遇到的问题和应对策略,怎么解决怎么做的问题。
通过深入本文可以理解代码原理,进行代码文档的下载,也可以查看相应 Demo 部署效果。

业务场景

在很多项目中,都有类似数据汇总的业务场景,查询今日注册会员数,在线会员数,订单总金额,支出总金额等。。。这些业务通常都不是存在同一张表中,我们需要依次查询出来然后封装成所需要的对象返回给前端。那么在此过程中,就可以把这个接口中“大任务”拆分成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<T>   : 消费型接口    void accept(T t);

 2、Supplier<T>      : 供给型接口    T get();

 3、Function<T,R>   : 函数型接口    R apply(T t);

 4、Predicate<T>    : 断言型接口    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.以上这种方式只能用在没有事务的业务中,因为在多线程中,事务是不共享的。

 

我恰芙蓉王资料部分资料来自网络,侵权毕设源码联系删除

区块链毕设网(www.qklbishe.com)全网最靠谱的原创区块链毕设代做网站
部分资料来自网络,侵权联系删除!
资源收费仅为搬运整理打赏费用,用户自愿支付 !
qklbishe.com区块链毕设代做网专注|以太坊fabric-计算机|java|毕业设计|代做平台 » 我恰芙蓉王资料

提供最优质的资源集合

立即查看 了解详情