springboot实现异步调用
异步调用特点
异步调用在开发程序中被广泛应用,在异步任务中,主线程不需要阻塞等待异步任务的完成,而是可以继续处理其他请求。
异步调用的特点如下:
- 非阻塞:主线程在调用异步方法后不会等待其完成,而是立即返回。
- 后台处理:耗时操作在后台独立的线程中执行,不会阻塞主线程。
- 资源利用率高:通过异步处理,可以更有效地利用系统资源,尤其是在需要处理大量并发请求时。
- 响应速度快:客户端会立即收到响应,而不需要等待耗时操作完成
线程池
线程池是一种基于池化思想管理和使用线程的机制。
它是将多个线程预先存储在一个“池子”内,当有任务出现时可以避免重新创建和销毁线程所带来性能开销,只需要从“池子”内取出相应的线程执行对应的任务即可。
线程池优点
- 降低资源消耗(复用线程,减少线程频繁新建、销毁等带来的开销)
- 提高响应速度
- 提高线程的可管理性
线程池任务执行流程如图所示
线程池主要参数
本例子是利用ThreadPoolExecutor创建的线程,主要参数如下所示:
- setCorePoolSize:核心线程数,线程池中始终存活的线程数。
- setMaxPoolSize:设置最大线程池大小,池中允许的最大线程数。
- setQueueCapacity:设置队列容量,当核心线程已满时,用于保存等待执行的任务的队列。
- initialize:初始化线程池
配置类代码
@Configuration
@EnableAsync
public class AsyncConfig {
@Bean(name = "taskExecutor")
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("Async-");
executor.initialize();
return executor;
}
}
AsyncConfig 类通过配置 ThreadPoolTaskExecutor 来管理异步任务的执行,设置了核心线程池大小、最大线程池大小、任务队列容量和线程名前缀等参数,并通过 @EnableAsync 注解启用了Spring的异步方法执行功能。
这样,当其他类中使用 @Async 注解标记的方法被调用时,异步任务将由配置的 taskExecutor 来执行。
服务类代码
@Service
public class AsyncService
{
@Async
public void performAsyncTask() {
System.out.println("Start async task - " + Thread.currentThread().getName());
try{
Thread.sleep(2000);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("End async task - " + Thread.currentThread().getName());
}
@Async
public void performAnotherAsyncTask() {
System.out.println("Start another async task - " + Thread.currentThread().getName());
try {
// 模拟长时间的任务
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("End another async task - " + Thread.currentThread().getName());
}
}
测试控制类代码
@RestController
@RequestMapping("/async")
public class AsyncController {
@Autowired
AsyncService asyncService;
@GetMapping("/test")
@UnInterception
public String test() {
System.out.println("Controller method call - " + Thread.currentThread().getName());
asyncService.performAsyncTask();
asyncService.performAnotherAsyncTask();
return "success";
}
}
运行结果
访问/async/test后,控制器会立即返回响应,而不会等待异步任务的完成,这正是体现了异步的特点,通过这种方式,可以提高系统的并发性和响应速度。