springboot的异步调用功能可以先释放容器分配给请求的线程与相关资源,减轻系统负担,提高响应效率,下图为在一种业务场景下的原理图
此功能为springboot自带,在启动类添加@EnableAsync注解
@EnableAsync
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
异步调用是会从线程池中获取线程,所以需要配置线程池
@Configuration
public class Config {
private static final int MAX_POOL_SIZE = 50;
private static final int CORE_POOL_SIZE = 20;
@Bean("asyncTaskExecutor")
public AsyncTaskExecutor asyncTaskExecutor() {
ThreadPoolTaskExecutor asyncTaskExecutor = new ThreadPoolTaskExecutor();
asyncTaskExecutor.setMaxPoolSize(MAX_POOL_SIZE);
asyncTaskExecutor.setCorePoolSize(CORE_POOL_SIZE);
asyncTaskExecutor.setThreadNamePrefix("异步线程-");
asyncTaskExecutor.initialize();
return asyncTaskExecutor;
}
}
使用时,只需要在方法上添加@Async注解即可,名称可填可不填,它会自动去线程池中获取线程
@Override
@Async("asyncTaskExecutor")
public String asynchronousMethod() {
try {
//让程序睡10s钟
Thread.sleep(10000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程名称 :" + Thread.currentThread().getName());
return "异步调用结束";
}
@Override
public String synchronizationMethod() {
System.out.println("线程名称 :" + Thread.currentThread().getName());
return "同步方法调用结束";
}
@RestController
public class AsynchronousDemoController {
@Autowired
private AsynchronousDemoService asynchronousDemoService;
@GetMapping("/demo/1")
public String demo() {
//开始时间
long startTime = System.currentTimeMillis();
//给当前线程起一个名字
Thread.currentThread().setName("同步线程");
//调用异步方法
String asynchronous = asynchronousDemoService.asynchronousMethod();
//调用同步方法
String synchronization = asynchronousDemoService.synchronizationMethod();
//结束时间
long endTime = System.currentTimeMillis();
String result = "异步结果: " + asynchronous + ":::::::::::" + "同步结果: " +
synchronization +
"\r\n所用时间: " + (endTime-startTime) + "ms";
System.out.println(result);
return result;
}
}
测试结果:可以看到异步线程是在此次请求结束后才执行完的,所以我们可以用它来处理一些耗时的业务,例如复杂的计算,循环判断等等,可以让前端更快的得到响应.