初探@Async

83 阅读3分钟

简介

1)在方法上使用该@Async注解,该方法是一个异步任务;

2)在类上面使用该@Async注解,该类中的所有方法都是异步任务;

3)方法上一旦标记了这个@Async注解,当其它线程调用这个方法时,就会开启一个新的子线程去异步处理该业务逻辑。

4)使用此注解的方法的类对象,必须是spring管理下的bean对象;

使用

在启动类上添加注解

@SpringBootApplication
@EnableAsync
public static void main(String[] args) {
		SpringApplication.run(VTokenApplication.class, args);
	}
@Async
public Future<List<Map<String, Object>>> queryAnnouncementList(ParamMap param,int index) {
		log.error(Thread.currentThread().getName()+"你看我是不是异步呢:"+index);
		int pageNo = param.getInt("pageNo", 1);
		int pageSize = param.getInt("pageSize", 20);
		pageNo = (pageNo - 1) * pageSize;
		
		return new AsyncResult<> (announcementRepository.queryAnnouncementList(pageNo,pageSize));

}

问题

2023-11-22 17:59:54,883 ERROR (AnnouncementService.java:34)- task-2你看我是不是异步呢:4579
2023-11-22 17:59:54,884 ERROR (AnnouncementService.java:34)- task-6你看我是不是异步呢:4580
2023-11-22 17:59:54,884 ERROR (AnnouncementService.java:34)- task-5你看我是不是异步呢:4581
2023-11-22 17:59:54,884 ERROR (AnnouncementService.java:34)- task-3你看我是不是异步呢:4582
2023-11-22 17:59:54,884 ERROR (AnnouncementService.java:34)- task-8你看我是不是异步呢:4583
2023-11-22 17:59:54,885 ERROR (AnnouncementService.java:34)- task-4你看我是不是异步呢:4584
2023-11-22 17:59:54,885 ERROR (AnnouncementService.java:34)- task-1你看我是不是异步呢:4585
2023-11-22 17:59:54,890 ERROR (AnnouncementService.java:34)- task-7你看我是不是异步呢:4586
2023-11-22 17:59:54,891 ERROR (AnnouncementService.java:34)- task-2你看我是不是异步呢:4587
2023-11-22 17:59:54,891 ERROR (AnnouncementService.java:34)- task-6你看我是不是异步呢:4588
2023-11-22 17:59:54,891 ERROR (AnnouncementService.java:34)- task-3你看我是不是异步呢:4589
2023-11-22 17:59:54,891 ERROR (AnnouncementService.java:34)- task-5你看我是不是异步呢:4590
2023-11-22 17:59:54,893 ERROR (AnnouncementService.java:34)- task-8你看我是不是异步呢:4591
2023-11-22 17:59:54,893 ERROR (AnnouncementService.java:34)- task-4你看我是不是异步呢:4592
2023-11-22 17:59:54,894 ERROR (AnnouncementService.java:34)- task-1你看我是不是异步呢:4593
2023-11-22 17:59:54,897 ERROR (AnnouncementService.java:34)- task-7你看我是不是异步呢:4594
2023-11-22 17:59:54,897 ERROR (AnnouncementService.java:34)- task-2你看我是不是异步呢:4595
2023-11-22 17:59:54,898 ERROR (AnnouncementService.java:34)- task-5你看我是不是异步呢:4596
2023-11-22 17:59:54,898 ERROR (AnnouncementService.java:34)- task-6你看我是

从这里可以看出默认的线程池是:

默认核心线程数:8,  
最大线程数:Integet.MAX_VALUE,
队列使用LinkedBlockingQueue,
容量是:Integet.MAX_VALUE,
空闲线程保留时间:60s,
线程池拒绝策略:AbortPolicy。

任务队列太大容易造成程序崩溃。

解决办法

自己自定义一个线程

@Configuration

public class AsyncConfig {
@Bean
public TaskExecutor taskExecutor() {
   	ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
   	executor.setCorePoolSize(10); // 设置核心线程数
   	executor.setMaxPoolSize(15); // 设置最大线程数
   	executor.setQueueCapacity(10); // 设置队列容量
   	executor.setKeepAliveSeconds(60); // 设置线程活跃时间(秒)
   	executor.setThreadNamePrefix("async-task-"); // 设置默认线程名称
   	executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());// 设置拒绝策略
   	executor.setWaitForTasksToCompleteOnShutdown(true); // 等待所有任务结束后再关闭线程池
   	return executor;
   }
   
}