本篇内容主要讲解“SpringBoot中异步调用@Async的方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“springBoot中异步调用@Async的方法
本篇内容主要讲解“SpringBoot中异步调用@Async的方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“springBoot中异步调用@Async的方法”吧!
在SpringBoot中,只需要给方法加上@Async注解,就能将同步方法变为异步调用。
首先在启动类上添加@EnableAsync,即开启异步调用。
@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; @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; @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<String> 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<String> 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<String> method3Result = task.method3(); Future<String> method4Result = task.method4(); //get方法为阻塞获取 log.info("method3执行的返回结果:{}", method3Result.get()); log.info("method4执行的返回结果:{}", method4Result.get()); log.info("main线程结束"); }
输出:
springboot一种全新的编程规范,其设计目的是用来简化新Spring应用的初始搭建以及开发过程,SpringBoot也是一个服务于框架的框架,服务范围是简化配置文件。
到此,相信大家对“SpringBoot中异步调用@Async的方法”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
--结束END--
本文标题: SpringBoot中异步调用@Async的方法
本文链接: https://www.lsjlt.com/news/71801.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-01-12
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0