Springboot Async异步扩展使用 结合 CompletableFuture

x33g5p2x  于2021-11-21 转载在 Spring  
字(1.4k)|赞(0)|评价(0)|浏览(558)

前言

很早前,出过一篇介绍springboot怎么使用异步线程的文章(如果你还未了解异步的使用,可以先看看这篇)

《SpringBoot 最简单的使用异步线程案例 @Async》:

https://blog.csdn.net/qq_35387940/article/details/83991594

然后近期有些小伙伴使用这个@Async的时候,私信我提出了一些业务场景,说需要拿返回值,但是又想结合‘异步’。

特别是调用第三方系统,怕耗时,不想调完一次再调一次。

其实,这种情形,就是一个典型的多线程处理场景。 

在一个主线程上,分叉出几个异步线程执行不同的逻辑,再看情况是否需要拿回异步线程的返回数据。
 

该篇文章,就是给大家带来基于@Async的使用,再结合 CompletableFuture 去实现我们刚提到的场景。

事不宜迟,进入主题。

正文

结合实例,给大家去讲解,介绍**@Async的使用,再结合 CompletableFuture 的使用。**

需求场景:

 

拉取第三方数据 ,分别需要拉取 A业务数据(需要2秒) 、拉取 B业务数据(需要2秒)、拉取 C业务数据(需要2秒) ,最后再一并返回给前端。

还涉及到了 超时调用的问题(项目要求每个接口不能超过 5秒 ),这时候就特别需要注意多线程的使用了。

这种情形,我们就会想到使用 异步:

写过模拟的测试接口:

运行结果我们看一下:

因为异步标记了三个方法,所以看到主线程时间没被受影响,但是同时返回值也拿不到。

这样  耗时接近0秒, 但是返回给前端的数据就是 null了。

当前的执行简图:

OK,就是基于当前这个情况,我们开始加入** CompletableFuture 的使用 。**

对代码进行改造一下:

调用模拟接口代码也需要跟着调整:

运行结果:

当前的执行简图:

为什么耗时是2秒,帮助理解:

CompletableFuture.allOf(a,b,c).join();
我们这里 allOf 传递了 三个 异步线程的返回值, 所以看到上图,也就出现了三个等待返回值的坑位 A B C。

可以把这个想象成一辆车,三个位, 必须人满才发车。

那么要等多久呢?
这三个人几乎是同时走向这辆车的,但是无论其他人走多快,因为得整整齐齐,所以

耗时取决于这三个坑位,最慢上车的那个人。

再次验证:

直接把pullDataA 改为等待8秒 ,

运行结果:
   

耗时 8秒

额外啰唆一下:

 

看到这,各位看官应该是都掌握怎么去使用操作 CompletableFuture 了。

只要我想要某个异步线程的返回值,我就把这个方法返回接收值CompletableFuture 加入到 allOf 里面去 。

对,这么使用确实是ok的。 

其实,只要你使用到了  返回接收值CompletableFuture ,其实就已经开始触发,并不是一定要用allOf。 

举例说明:

ps:那么我们怎么去使用这个CompletableFuture ,大家应该多少会玩了吧。 

再啰唆一下,

其实我的这个打印输出,
 

System.out.println(a.get()+b.get()+c.get());

里面也调用了get() ,也就是也算是使用了。

那么再举一个小例子:

这种情况,我们使用了 CompletableFuture<String>分别去接收返回值,但是我们后面没去使用操作它们,也没使用allOf , 看下运行结果:

也就是说,这种情况,不会因为 我们使用了 CompletableFuture 而促使让主线程去等待任何异步线程。

OK,该篇就到这吧。

相关文章