在SpringBoot中,只需要给方法加上@Async注解,就能将同步方法变为异步调用。

首先在启动类上添加@EnableAsync,即开启异步调用。
- /**
 - * @author qcy
 - */
 - @SpringBootApplication
 - @EnableAsync
 - public class AsyncApplication {
 - public static void main(String[] args) {
 - SpringApplication.run(AsyncApplication.class, args);
 - }
 - }
 
在需要异步调用的方法上加上@Async注解
- package com.yang.async;
 - import lombok.extern.slf4j.Slf4j;
 - import org.springframework.scheduling.annotation.Async;
 - import org.springframework.scheduling.annotation.AsyncResult;
 - import org.springframework.stereotype.Component;
 - import java.util.concurrent.Future;
 - import java.util.concurrent.FutureTask;
 - /**
 - * @author qcy
 - * @create 2020/09/09 14:01:35
 - */
 - @Slf4j
 - @Component
 - public class Task {
 - @Async
 - public void method1() {
 - log.info("method1开始,执行线程为" + Thread.currentThread().getName());
 - try {
 - Thread.sleep(2000);
 - } catch (InterruptedException e) {
 - e.printStackTrace();
 - }
 - log.info("method1结束");
 - }
 - @Async
 - public void method2() {
 - log.info("method2开始,执行线程为" + Thread.currentThread().getName());
 - try {
 - Thread.sleep(3000);
 - } catch (InterruptedException e) {
 - e.printStackTrace();
 - }
 - log.info("method2结束");
 - }
 - }
 
测试一下:
- @SpringBootTest
 - @Slf4j
 - public class AsyncApplicationTests {
 - @Autowired
 - Task task;
 - @Test
 - public void testAsyncWithVoidReturn() throws InterruptedException {
 - log.info("main线程开始");
 - task.method1();
 - task.method2();
 - //确保两个异步调用执行完成
 - Thread.sleep(6000);
 - log.info("main线程结束");
 - }
 - }
 
输出如下:
可以看得出,SpringBoot创建了一个名为applicationTaskExecutor的线程池,使用这里面的线程来执行异步调用。
这里值得注意的是,不要在一个类中调用@Async标注的方法,否则不会起到异步调用的作用,至于为什么会产生这样的问题,需要深入到源码中一探究竟,会另开篇幅。
既然默认使用的是SpringBoot自己创建的applicationTaskExecutor,那如何自己去定义一个线程池呢?
我们需要手动创建一个名为asynTaskExecutord的Bean
- package com.yang.async;
 - import lombok.extern.slf4j.Slf4j;
 - import org.springframework.context.annotation.Bean;
 - import org.springframework.context.annotation.Configuration;
 - import org.springframework.core.task.AsyncTaskExecutor;
 - import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 - import java.util.concurrent.ThreadPoolExecutor;
 - /**
 - * @author qcy
 - * @create 2020/09/09 15:31:07
 - */
 - @Slf4j
 - @Configuration
 - public class AsyncConfig {
 - @Bean
 - public AsyncTaskExecutor asyncTaskExecutor() {
 - ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
 - executor.setCorePoolSize(8);
 - executor.setMaxPoolSize(16);
 - executor.setQueueCapacity(50);
 - executor.setAllowCoreThreadTimeOut(true);
 - executor.setKeepAliveSeconds(10);
 - executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
 - executor.setThreadNamePrefix("async-thread-pool-thread");
 - return executor;
 - }
 - }
 
对以上参数不了解的同学,可以参考我的这篇文章说说线程池
其他类不需要变动,直接运行刚才的testAsyncWithVoidReturn()方法,输出:
看得出来,现在是我们自定义的线程池
如果关心异步调用的返回值,又怎么处理?
获取异步调用的结果,需要利用Future机制,可以参考我的另外一篇文章谈谈Runnable、Future、Callable、FutureTask之间的关系
为Task类增加以下两个方法:
- @Async
 - public Future
 method3() { - log.info("method3开始,执行线程为" + Thread.currentThread().getName());
 - try {
 - Thread.sleep(1000);
 - } catch (InterruptedException e) {
 - e.printStackTrace();
 - }
 - log.info("method3结束");
 - return new AsyncResult<>("method3");
 - }
 - @Async
 - public Future
 method4() { - log.info("method4开始,执行线程为" + Thread.currentThread().getName());
 - try {
 - Thread.sleep(3000);
 - } catch (InterruptedException e) {
 - e.printStackTrace();
 - }
 - log.info("method4结束");
 - return new AsyncResult<>("method4");
 - }
 
测试类:
- @Test
 - public void testAsyncWithStringReturn() throws InterruptedException, ExecutionException {
 - log.info("main线程开始");
 - Future
 method3Result = task.method3(); - Future
 method4Result = task.method4(); - //get方法为阻塞获取
 - log.info("method3执行的返回结果:{}", method3Result.get());
 - log.info("method4执行的返回结果:{}", method4Result.get());
 - log.info("main线程结束");
 - }
 
输出:
如图,在主线程结束前,获取到了异步调用的结果。且在两个异步调用都结束的情况下,继续执行主线程。
                分享标题:详解SpringBoot中的异步调用@Async
                
                地址分享:http://www.csdahua.cn/qtweb/news26/430826.html
            
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网