@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做了标注,则可实现事务控制的目的。

 
posted @ 2022-06-08 16:55  X_peng  阅读(618)  评论(0编辑  收藏  举报