一. 什么是异步调用?
异步调用是相对于同步调用而言的,同步调用是指程序按预定顺序一步步执行,每一步必须等到上一步执行完后才能执行,异步调用则无需等待上一步程序执行完即可执行。
二. 如何实现异步调用?
多线程,这是很多人第一眼想到的关键词,没错,多线程就是一种实现异步调用的方式。在非spring目项目中我们要实现异步调用的就是使用多线程方式,可以自己实现Runable接口或者集成Thread类,或者使用jdk1.5以上提供了的Executors线程池。在spring 3.x之后,就已经内置了@Async来完美解决这个问题,下面将介绍在springboot中如何使用@Async。
SpringBoot异步注解@Async生效必要条件
1)在@SpringBootApplication启动类 添加注解@EnableAsync
2)异步方法使用注解@Async ,返回值为void或者Future
3)切记一点 ,异步方法和调用方法一定要 写在不同的类中 ,如果写在一个类中,是没有效果的。
demo
配置自定义线程池
@Configuration
public class ThreadConf {
@Bean
public ThreadPoolTaskExecutor asyncExecutor(){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//设置核心数线程
executor.setCorePoolSize(16);
//设置最大线程数
executor.setMaxPoolSize(64);
//设置队列大小
executor.setQueueCapacity(999);
//设置线程池名称前缀
executor.setThreadNamePrefix("async-my");
//设置线程超过的拒绝策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//初始化
executor.initialize();
return executor;
}
}
启动类开启异步
//开启异步
@EnableAsync
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class);
}
}
模拟异步发短信
@Service
public class AsyncServcieImpl {
@Async(value = "asyncExecutor")
//制定线程池名称
public Future<String> sendEmail() throws InterruptedException {
Thread.sleep(1000);
for (int i = 0; i < 10; i++) {
System.out.println("发生短信");
}
return new AsyncResult<>("success");
}
}
@GetMapping("/all/sendEmail")
public String sendEmail() throws InterruptedException, ExecutionException {
System.out.println("=========开始发短信====");
Future<String> stringFuture = asyncServcie.sendEmail();
System.out.println("=========结束发短信====");
//结果处于阻塞,有结果才会获取值
return stringFuture.get();
}
预想如果异步注解成功那么打印台会
=====开始发短信
=====结束发短信
发生短信…