Springboot Async异步扩展使用 结合 CompletableFuture

简介: Springboot Async异步扩展使用 结合 CompletableFuture

前言



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


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


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


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


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


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


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


事不宜迟,进入主题。


正文



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


需求场景:


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


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


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


image.png


写过模拟的测试接口:


image.png


运行结果我们看一下:


image.png 


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


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


当前的执行简图:


image.png


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


对代码进行改造一下:


image.png


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

image.png


运行结果:


image.png


当前的执行简图:

image.png


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


CompletableFuture.allOf(a,b,c).join();


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


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


那么要等多久呢?


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


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


再次验证:


直接把pullDataA 改为等待8秒 ,


image.png运行结果:

 

耗时 8秒


image.png


额外啰唆一下:


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


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


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


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


举例说明:


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


image.png


再啰唆一下,


其实我的这个打印输出,

 

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

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


那么再举一个小例子:


image.png


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


image.png


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


OK,该篇就到这吧。

相关文章
|
8月前
|
前端开发 Java 应用服务中间件
Springboot对MVC、tomcat扩展配置
Springboot对MVC、tomcat扩展配置
|
5月前
|
Java 开发者 Spring
【SpringBoot 异步魔法】@Async 注解:揭秘 SpringBoot 中异步方法的终极奥秘!
【8月更文挑战第25天】异步编程对于提升软件应用的性能至关重要,尤其是在高并发环境下。Spring Boot 通过 `@Async` 注解简化了异步方法的实现。本文详细介绍了 `@Async` 的基本用法及配置步骤,并提供了示例代码展示如何在 Spring Boot 项目中创建与管理异步任务,包括自定义线程池、使用 `CompletableFuture` 处理结果及异常情况,帮助开发者更好地理解和运用这一关键特性。
351 1
|
2月前
|
Java 开发者 Spring
精通SpringBoot:16个扩展接口精讲
【10月更文挑战第16天】 SpringBoot以其简化的配置和强大的扩展性,成为了Java开发者的首选框架之一。SpringBoot提供了一系列的扩展接口,使得开发者能够灵活地定制和扩展应用的行为。掌握这些扩展接口,能够帮助我们写出更加优雅和高效的代码。本文将详细介绍16个SpringBoot的扩展接口,并探讨它们在实际开发中的应用。
58 1
|
3月前
|
监控 Java 开发者
掌握SpringBoot扩展接口:提升代码优雅度的16个技巧
【10月更文挑战第20天】 SpringBoot以其简化配置和快速开发而受到开发者的青睐。除了基本的CRUD操作外,SpringBoot还提供了丰富的扩展接口,让我们能够更灵活地定制和扩展应用。以下是16个常用的SpringBoot扩展接口,掌握它们将帮助你写出更加优雅的代码。
113 0
|
5月前
|
Java 开发者 Spring
"揭秘SpringBoot魔法SPI机制:一键解锁服务扩展新姿势,让你的应用灵活飞天!"
【8月更文挑战第11天】SPI(Service Provider Interface)是Java的服务提供发现机制,用于运行时动态查找和加载服务实现。SpringBoot在其基础上进行了封装和优化,通过`spring.factories`文件提供更集中的配置方式,便于框架扩展和组件替换。本文通过定义接口`HelloService`及其实现类`HelloServiceImpl`,并在`spring.factories`中配置,结合`SpringFactoriesLoader`加载服务,展示了SpringBoot SPI机制的工作流程和优势。
77 5
|
5月前
|
监控 Java API
Spring Boot中的异步革命:构建高性能的现代Web应用
【8月更文挑战第29天】Spring Boot 是一个简化 Spring 应用开发与部署的框架。异步任务处理通过后台线程执行耗时操作,提升用户体验和系统并发能力。要在 Spring Boot 中启用异步任务,需在配置类上添加 `@EnableAsync` 注解,并定义一个自定义的 `ThreadPoolTaskExecutor` 或使用默认线程池。通过 `@Async` 注解的方法将在异步线程中执行。异步任务适用于发送电子邮件、数据处理、外部 API 调用和定时任务等场景。最佳实践中应注意正确配置线程池、处理返回值和异常、以及监控任务状态,确保系统的稳定性和健壮性。
47 0
|
5月前
|
Java 开发者 Spring
Spring Boot大法好:解耦、隔离、异步,让代码‘活’起来,性能飙升的秘密武器!
【8月更文挑战第29天】解耦、隔离与异步是Spring Boot中的关键设计原则,能大幅提升软件的可维护性、扩展性和性能。本文通过示例代码详细探讨了这些原则的应用:依赖注入和面向接口编程实现解耦;模块化设计与配置文件实现隔离;`@Async`注解和`CompletableFuture`实现异步处理。综合运用这些原则,可以显著提升软件质量和性能,使系统更加健壮、灵活和高效。
56 0
|
6月前
|
Java Spring 容器
Spring boot 自定义ThreadPoolTaskExecutor 线程池并进行异步操作
Spring boot 自定义ThreadPoolTaskExecutor 线程池并进行异步操作
301 3
|
7月前
|
监控 Java 应用服务中间件
Spring Boot应用的部署与扩展
Spring Boot应用的部署与扩展
|
6月前
|
安全 Java 数据库连接
Spring Boot 优雅关机时异步线程安全优化
Spring Boot 优雅关机时异步线程安全优化
150 1
下一篇
开通oss服务