业务场景中使用异步多线程的使用CompletableFuture减少接口耗时

329 阅读2分钟

      开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情

CompletableFuture的特性理解

以前使用多线程处理的时候,常用的就是实现Runnable接口或者callable接口,然后通过线程池submit()或者execute();如果是submit()可以用Future来进行接受

CompletableFuture我的理解就是集合封装了上述能力的集合;;

  • Callable就是具有返回结果的动作任务
  • Runable 就是没有无返回值的动作任务
  • Future 里面封装了callable和runable的能力,然后交给线程池使用执行,如果需要结果就future.get()或者结果
  • CompletableFuture即而封装了future,使其拥有了回调的功能,在某个行为动作完成之后,继续进行下一个动作。有点链式编程的意思;

话不多说上例子

   public static void main(String[] args) throws InterruptedException {

       long curr = System.currentTimeMillis();
       ExecutorService executorService = Executors.newFixedThreadPool(10);
//        List<String> list = new ArrayList();
       List<String> list = Collections.synchronizedList(new ArrayList<String>());

        int d = 10;
       CountDownLatch countDownLatch = new CountDownLatch(11);
       for (int i=0;i<=d;i++){
            int  finalI = i;
           CompletableFuture.runAsync(() ->{
               System.out.println(Thread.currentThread().getName() + "---时间"+System.currentTimeMillis());
               list.add( PolicyTaskRepositoryImpl.addX(finalI));
               countDownLatch.countDown();

           },executorService);

       }
       countDownLatch.await();


       long now = System.currentTimeMillis();
       System.out.println("耗时:"+(now-curr)/1000+  "秒"+ JSON.toJSONString(list));

   }
   public static String addX(int x){
       try {
           Thread.sleep(2000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       return x+"dds";
   }

执行结果:

image.png

解析代码

代码中的逻辑就是for循环中重复调用某个耗时方法(可以类比为数据库),此时加上多线程并行查询,然后等待所有的子线程执行完成之后,再将结果聚合到list中返回

  • Collections.synchronizedList(new ArrayList()) 为了防止结果插入到Arraylist中# 多线程高并发情况下ArrayList集合不安全问题
  • CountDownLatch 可以理解为就是一个计数器,目的是确认所有的子线程都跑完了,再执行main线程
  • CompletableFuture.runAsync() 异步执行 不需要返回值
  • CompletableFuture.supplyAsync() 异步执行 ,需要返回值使用

总结

上述例子是业务场景中的一个简化单demo,效果是接口从22秒减少到了2秒以内,所以在某些使用的时候还是很有用的,但是异步执行有一个问题就是traceId日志链路不太好串起来,就看各个公司有没有分布式日志底层工具。。每日记录一点点🤏