• Java并发编程—CompletableFuture的异步执行案例


            在博主前几篇博客中,https://blog.csdn.net/qq_52545155/article/details/128167519?spm=1001.2014.3001.5501,给大家分享了关于多线程中异步任务的执行和一些相关概念,在这篇博客中,主要是通过一个实际的案例让大家对于CompletableFuture的用法有一个深入的理解

    🍏一、需求分析

            临近过年了,很多铁子都有购物的需求,那么大家肯定想花更少的钱去买相同的一个产品,例如茅台酒在不同的购物平台或者不同的商家里面价格是不一样的,例如:

    🍕jd

    🍕tb:

           图中这些价格都是不一样的,所以大家就会有一个需求,能不能把这个当作一个程序进行一个数据统计,统计出不同平台的茅台价格,然后自己根据价格、商家来购买,这个例子大家都明白,其实在工作中也有很多这种的需求,那么针对这种需要统计的需求业务我们该怎么去做呢?

    🍏二、方案设计

            相信很多铁子有心里有方案:

            🍄1、一个一个的进行记录,或者用爬虫去爬

            🍄2、用异步多线程进行统计,这这里博主会分享第二种的实践方式

    🍏三、代码展示

            前面是举个例子,这个并不会去搜刮数据哈,大家对于接口api的调用可以自行补充,主要分享思维,商城在代码种是以对象实体存在的;    

    🍄1、先准备一个商城公共类

    1. class ShoppMall{
    2. private String mallName;
    3. public String getMallName() {
    4. return mallName;
    5. }
    6. public ShoppMall(String mallName) {
    7. this.mallName = mallName;
    8. }
    9. /*商城存在了,这里提供一个根据输入的商品名返回一个价格的方法*/
    10. public Double getPrice(String commodityName){
    11. //模拟检索用时1s
    12. try {
    13. TimeUnit.SECONDS.sleep(1);
    14. } catch (InterruptedException e) {
    15. e.printStackTrace();
    16. }
    17. //高并发多线程使用ThreadLocalRandom
    18. return ThreadLocalRandom.current().nextDouble()*2+commodityName.charAt(0);
    19. }
    20. }

    🍄2、业务开始前还需要实例化几个具体的商城对象出来,这样才能通过上面的getPrice()方法获取到价格

    1. public class CSDNCompletableFutureDemo {
    2. //实例化几个商城对象,放到集合中
    3. private static List list= Arrays.asList(new ShoppMall("jd"),
    4. new ShoppMall("tb"),
    5. new ShoppMall("pdd")
    6. );
    7. }

    🍄3、一个商城一个商城进行搜索的操作,代码如下:

    1. /*一个一个的从商城进行搜索一个商品,然后返回一个格式化好了的集合*/
    2. public static List stepSearch(List list,String comName){
    3. return list.stream().map(mall -> {
    4. System.out.println(mall.getMallName() + "正在查找" + comName);
    5. return String.format("%s 的 %s 价格是%.2f", mall.getMallName(), comName, mall.getPrice(comName));
    6. }).collect(Collectors.toList());
    7. }

    🍄4、这个时候我们可以先对其进行一个测试,看看效果如何:

    1. public static void main(String[] args) {
    2. long startTime = System.currentTimeMillis();
    3. List search1 = stepSearch(list, "茅台");
    4. for (String s : search1) {
    5. System.out.println(s);
    6. }
    7. System.out.println("本次用时"+(System.currentTimeMillis()-startTime)+"毫秒");
    8. }

    效果如下:

    🚗总结:这里每一个商城搜索都用了1s,然后加上其他的耗时,一共是3061毫秒,代码着我有多少个平台,至少就要花n+秒的时间,显然这个很不能让人接收,那么在我们用Compleatable如何去实现呢,接着往下看;

    🍄5、用异步多线程进行执行,代码如下:

    1. /*用CompletableFuture异步多线程进行搜索,然后返回一个格式化好了的集合*/
    2. public static List synSearch(List list, String comName) {
    3. return list.stream().map(mall -> {
    4. System.out.println(mall.getMallName() + "正在查找" + comName);
    5. return CompletableFuture.supplyAsync(() -> {
    6. return String.format("%s 的 %s 价格是%.2f", mall.getMallName(), comName, mall.getPrice(comName));
    7. });
    8. }).collect(Collectors.toList()).stream().map(CompletableFuture::join).collect(Collectors.toList());
    9. }

    运行代码:

    1. public static void main(String[] args) {
    2. long startTime = System.currentTimeMillis();
    3. // List search1 = stepSearch(list, "茅台");
    4. List search1 = synSearch(list, "茅台");
    5. for (String s : search1) {
    6. System.out.println(s);
    7. }
    8. System.out.println("本次用时" + (System.currentTimeMillis() - startTime) + "毫秒");
    9. }

    效果图:

    🚗总结:每个商城检索要一秒,而这种方式相当于是在一秒钟,多个商城同时进行搜索,然后将结果进行了返回,达到了万箭齐发的效果,这也正是我们想要的。

    🍏四、总结

            🍄1、博主分别用了2种方式,传统方式的one by one一个一个的搜索是非常耗时且效率低下

            🍄2、采用多线程同时进行搜索,节约时间节约成本,是我们想要的效果

            🍄3、实现功能是每个程序员都要完成的,但是最终都是靠性能说服别人,这里是3个商城,普通的就要3s+,而异步执行只需要一秒即可完成,假如我多实例化一个商城,普通方式就需要多一秒,而异步还是只要一秒,显然比one by one来得更有力,这就是为啥高并发这么使人神往;

            🍄4、当商城实例足够多了的话,可以不选择用CompletableFuture自带的线程池,可以自定义线程池然后进行传入使用。还可以分批次进行线程执行,都是一些优化手段;

             🍄4、代码很多是Stream流和Lambda表达式,需要大家把代码运行看一下效果就可以理解

  • 相关阅读:
    React与Vue的区别
    微积分学习笔记(2):用Go语言画函数图像
    【数据挖掘 & 机器学习 | 时间序列】时间序列必备工具箱: 自相关与偏相关检验
    java计算机毕业设计高校车辆管理系统MyBatis+系统+LW文档+源码+调试部署
    class09:ejs模块
    144. 二叉树的前序遍历-C语言
    每日一题~二叉搜索树中的插入操作
    PowerShell 查看 命令 所有的 参数
    计网个人作业02
    11、时序约束
  • 原文地址:https://blog.csdn.net/qq_52545155/article/details/128212148