@Async—异步注解实现多线程
在Java中多线程完成的任务,在Spring 3.x之后,就已经内置了@Async来完美解决。
注意事项:
-
必须用在public方法上,且不能是static方法
-
不能与调用的方法在同一个类中
-
需要把该方法注入到Spring容器中,就是在一个类中添加异步方法,并在此类上使用@Component之类的注解加入到容器
步骤:
先在springboot启动类上添加 @EnableAsync 注解。
再在对应方法上添加@Async注解:
1、无返回的void方法:直接添加@Async注解。
2、有返回值的方法:使用Future<String>类型返回。这种方法是通过不停的检查Future的状态来获取当前的异步方法是否执行完毕来实现的。
3、使用自定义的线程池:在 @Async 注解的括号里加上自定义的线程池的bean即可。
/**
* 线程池配置
* @param
* @return java.util.concurrent.Executor
*/
@Bean(name = "threadPoolTaskExecutor")
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
logger.info("---------- 线程池开始加载 ----------");
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
// 核心线程池大小
threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
// 最大线程数
threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
// 队列容量
threadPoolTaskExecutor.setQueueCapacity(keepAliveSeconds);
// 活跃时间
threadPoolTaskExecutor.setKeepAliveSeconds(queueCapacity);
// 主线程等待子线程执行时间
threadPoolTaskExecutor.setAwaitTerminationSeconds(awaitTerminationSeconds);
// 线程名字前缀
threadPoolTaskExecutor.setThreadNamePrefix(threadNamePrefix);
// RejectedExecutionHandler:当pool已经达到max-size的时候,如何处理新任务
// CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行
threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 初始化
threadPoolTaskExecutor.initialize();
logger.info("---------- 线程池加载完成 ----------");
return threadPoolTaskExecutor;
}
@Async(“threadPoolTaskExecutor”)
public void fun(){//...}
4、事务处理机制 可以将需要事务管理操作的方法放置到异步方法内部,在内部被调用的方法上添加@Transactional。 例:方法B,使用了@Async来标注,B中调用了C、D。C/D分别使用@Transactional做了标注,则可实现事务控制的目的。
Keep moving forwards~