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对象所在地址会替换掉原本的参数地址,所以主线程中的集合并没有发生变化。如下图所示

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lllllLiangjia

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值