Springboot @Async 多线程获取返回值

Springboot @Async 多线程获取返回值

需求背景

最近需要用到多线程, 自己维护线程池很麻烦, 正好看到Springboot集成线程池的例子, 这里自己做了个尝试和总结, 记录一下, 也分享给需要的朋友;

不考虑事务的情况下, 这个多线程实现比较简单, 主要有以下几点:

  1. 在启动类加上@EnableAsync注解, 开启异步执行支持;
  2. 编写线程池配置类, 别忘了@Configuration, 和@Bean注解;
  3. 编写需要异步执行的业务, 放到单独的类中 (可以定义为 service, 因为需要 spring 管理起来才能用 );

举栗个现实问题:

需求 :拉取 业务数据不能超过 5秒。

拉取第三方数据 ,分别需要拉取 A业务数据(需要2秒) 、拉取 B业务数据(需要2秒)、拉取 C业务数据(需要2秒) ,最后再一并返回给前端。
解决方案 : Executor+@Async("参数")+CompletableFutureFuture

上代码

1.启动类上加注解

java 复制代码
@EnableAsync

2.配置类

其他配置请参考配置类示例

java 复制代码
@Slf4j
//@EnableAsync//(该注解加在启动类或线程池配置类上都可以)
@Configuration
public class ThreadPoolCommonConfig extends AsyncConfigurerSupport {
    @Bean("asyncExecutor")
    public Executor asyncExecutor() {
		ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(20);
        taskExecutor.setMaxPoolSize(100);
        taskExecutor.setQueueCapacity(1000);
        taskExecutor.setKeepAliveSeconds(60);
        taskExecutor.setThreadNamePrefix("asyncExecutorConfig--");
        taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        taskExecutor.setAwaitTerminationSeconds(60);
        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        // MDC 装饰器  传递MDC中的信息
        taskExecutor.setTaskDecorator(new MdcTaskDecorator());
        return taskExecutor;
    }
}

3.异步方法(所属类需交由Spring管理)

3.1.@Async + CompletableFuture(推荐)

java 复制代码
@Override
@Async("asyncExecutor")
public CompletableFuture<String> list(String s) {
    log.info("{}: {}", s, Thread.currentThread().getName());
    ThreadUtil.sleep(2, TimeUnit.SECONDS);
    log.info("{}查询列表成功", s);
    return CompletableFuture.completedFuture(s);
}

3.2.@Async + Future

java 复制代码
// 异步执行的方法, 注解内为自定义线程池类名
@Override
@Async("asyncExecutor")
public Future<Integer> test(Integer i) {
    log.info("{}: {}", i, Thread.currentThread().getName());
    ThreadUtil.sleep(1, TimeUnit.SECONDS);
    log.info("@Async执行:{}", i);
    return new AsyncResult(i);
}

4.调用

4.1.CompletableFuture获取返回值(推荐)

java 复制代码
CompletableFuture<String> future1 = testService.list("A");
CompletableFuture<String> future2 = testService.list("B");
// 阻塞所有异步线程执行完毕
CompletableFuture.allOf(future1, future2).join();
// 阻塞,直至 future1 和 future2 的异步线程执行完毕
log.info("future结果:{},{}", future1.get(), future2.get());

4.2.Future获取返回值

java 复制代码
Future<Integer> future1 = testService.test(1);
Future<Integer> future2 = testService.test(2);
// 阻塞,直至 future1 的异步线程执行完毕
log.info("future1结果:{}", future1.get());
// 阻塞,直至 future2 的异步线程执行完毕
log.info("future1结果:{}", future2.get());

参考文档

Async注解使用和CompletableFuture注解获取返回值
Springboot @Async 多线程获取返回值
Spring Boot中调用@Async注解的异步方法并获取返回值

相关推荐
sjsjsbbsbsn1 小时前
Spring Boot定时任务原理
java·spring boot·后端
计算机毕设指导61 小时前
基于Springboot学生宿舍水电信息管理系统【附源码】
java·spring boot·后端·mysql·spring·tomcat·maven
计算机-秋大田2 小时前
基于Spring Boot的兴顺物流管理系统设计与实现(LW+源码+讲解)
java·vue.js·spring boot·后端·spring·课程设计
小蒜学长3 小时前
医疗报销系统的设计与实现(代码+数据库+LW)
数据库·spring boot·学习·oracle·课程设计
橘猫云计算机设计4 小时前
基于SSM的《计算机网络》题库管理系统(源码+lw+部署文档+讲解),源码可白嫖!
java·数据库·spring boot·后端·python·计算机网络·毕设
小盼江4 小时前
水果生鲜农产品推荐系统 协同过滤余弦函数推荐水果生鲜农产品 Springboot Vue Element-UI前后端分离 代码+开发文档+视频教程
vue.js·spring boot·ui
坚定信念,勇往无前4 小时前
Spring Boot中整合Flink CDC 数据库变更监听器来实现对MySQL数据库
数据库·spring boot·flink
坚定信念,勇往无前5 小时前
Spring Boot 如何保证接口安全
spring boot·后端·安全
尚学教辅学习资料6 小时前
基于SpringBoot+Vue+uniapp的高校招聘小程序+LW参考示例
spring boot·uni-app·招聘系统
m0_748247558 小时前
springboot中配置logback-spring.xml
spring boot·spring·logback