Spring Boot中调用@Async注解的异步方法并获取返回值
Posted lllllLiangjia
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Boot中调用@Async注解的异步方法并获取返回值相关的知识,希望对你有一定的参考价值。
该方法无需创建任何实体,只需要通过传参即可获取返回结果
需求背景
最近正在研发的系统有接口需要从多个表中获取数据进行处理,所以打算使用多线程异步获取到这几个表处理后的数据结果。由于Spring Boot提供多线程ThreadPoolTaskExecutor类,使用代码如下
代码
配置类
@Configuration
public class ThreadPoolConfig
@Value("$threadpool.core-pool-size")
private int corePoolSize;
@Value("$threadpool.max-pool-size")
private int maxPoolSize;
@Value("$threadpool.queue-capacity")
private int queueCapactiy;
@Value("$threadpool.keep-alive-seconds")
private int keepAliveSeconds;
// 配置线程前缀
@Value("$threadpool.name-prefix")
private String namePrefix;
@Bean("taskExecutor")
public ThreadPoolTaskExecutor threadPoolTaskExecutor()
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setKeepAliveSeconds(keepAliveSeconds);
threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
threadPoolTaskExecutor.setQueueCapacity(queueCapactiy);
threadPoolTaskExecutor.setThreadNamePrefix(namePrefix);
threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
threadPoolTaskExecutor.initialize();
return threadPoolTaskExecutor;
配置文件
# 多线程
threadpool.core-pool-size=xx
threadpool.max-pool-size=xx
threadpool.queue-capacity=xxx
threadpool.keep-alive-seconds=xxx
threadpool.name-prefix=taskExecutorInitData
启动类上加注解
@EnableAsync
业务逻辑代码
@Autowired
MedicalServiceService medicalServiceService;
public void initData(String personId) throws InterruptedException
CountDownLatch countDownLatch = new CountDownLatch(4);
// 就诊数据
List<DataVisitBasicDo> visitBasic = new ArrayList<>();
medicalServiceService.getVisitBasicFromBigData(visitBasic, countDownLatch);
// 检查数据
List<DataVisitExamDo> visitExam = new ArrayList<>();
medicalServiceService.getVisitExamFromBigData(visitExam, countDownLatch);
异步方法
@Async("taskExecutor")
public void getVisitBasicFromBigData(
List<DataVisitBasicDo> visitBasicFromBigData,CountDownLatch countDownLatch)
// 从数据库中查出来的集合数据
List<DataVisitBasicBigDo> lists = dataVisitBigDataDao.getTest1();
// 处理过程......
visitExamFromBigData.addAll(lists);
// 该代码无效
// visitExamFromBigData = lists
countDownLatch.countDown();
@Async("taskExecutor")
public void getVisitExamFromBigData(
List<DataVisitExamDo> visitExamFromBigData, CountDownLatch countDownLatch)
// 从数据库中查出来的集合数据
List<DataVisitExamBigDo> lists = dataVisitBigDataDao.getTest2();
// 处理过程......
visitExamFromBigData.addAll(lists);
// 该代码无效
// visitExamFromBigData = lists
countDownLatch.countDown();
不可与调用方在同一个类中,否则异步调用无效,是串行执行
注意:
想要获取异步方法中处理后的数据结果,可以直接通过传参进行接收,众所周知,引用类型传参传的是地址,我们可以根据参数地址对应的对象集合进行add操作,这样就可以把异步处理的数据结果返回给主线程了。
那为什么直接用等于号就回失效呢?
visitExamFromBigData = lists,lists对象所在地址会替换掉原本的参数地址,所以主线程中的集合并没有发生变化。如下图所示
以上是关于Spring Boot中调用@Async注解的异步方法并获取返回值的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot中调用@Async注解的异步方法并获取返回值
Spring Boot中调用@Async注解的异步方法并获取返回值