Springboot @Async 多线程获取返回值

需求背景

最近需要用到多线程, 自己维护线程池很麻烦, 正好看到Springboot集成线程池的例子, 这里自己做了个尝试和总结, 记录一下, 也分享给需要的朋友; 不考虑事务的情况下, 这个多线程实现比较简单, 主要有以下几点:

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

举栗个现实问题:

需求:拉取 业务数据不能超过 5秒。 拉取第三方数据 ,分别需要拉取 A业务数据(需要2秒) 、拉取 B业务数据(需要2秒)、拉取 C业务数据(需要2秒) ,最后再一并返回给前端。 解决方案: Executor+@Async(“参数”)+CompletableFuture 或 Future

上代码

1.启动类上加注解

@EnableAsync

2.配置类

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

@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(推荐)

@Override

@Async("asyncExecutor")

public CompletableFuture 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

// 异步执行的方法, 注解内为自定义线程池类名

@Override

@Async("asyncExecutor")

public Future 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获取返回值(推荐)

CompletableFuture future1 = testService.list("A");

CompletableFuture future2 = testService.list("B");

// 阻塞所有异步线程执行完毕

CompletableFuture.allOf(future1, future2).join();

// 阻塞,直至 future1 和 future2 的异步线程执行完毕

log.info("future结果:{},{}", future1.get(), future2.get());

4.2.Future获取返回值

Future future1 = testService.test(1);

Future future2 = testService.test(2);

// 阻塞,直至 future1 的异步线程执行完毕

log.info("future1结果:{}", future1.get());

// 阻塞,直至 future2 的异步线程执行完毕

log.info("future1结果:{}", future2.get());

参考文档

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

好文阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: