SpringBoot使用@Async注解实现异步调用

ゞ 浴缸里的玫瑰 2023-10-04 08:32 30阅读 0赞

什么是@Async
被@Async标注的方法,称之为异步方法,会被独立的线程所执行,调用者无需等待它执行完毕,也可以执行其他操作。@Async标注在类上,表明类的所有方法都是异步方法

@Async的具体使用
1、在项目启动类上加上@EnableAsync注解,表明开启异步调用
在这里插入图片描述
2、自定义线程池

  1. package com.example.task.config;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.scheduling.annotation.EnableAsync;
  5. import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
  6. import java.util.concurrent.Executor;
  7. import java.util.concurrent.ThreadPoolExecutor;
  8. @EnableAsync
  9. @Configuration
  10. public class ExecutorConfig {
  11. private static final int CORE_POOL_SIZE=Runtime.getRuntime().availableProcessors();
  12. private static final int MAX_POOL_SIZE=2*CORE_POOL_SIZE;
  13. private static final int KEEPALIVE_SECONDS=60;
  14. private static final int QUERY_CAPACITY=128;
  15. private static final int AVAIL_TERMINATION_MILLIS=60;
  16. private static final String THREAD_NAME_PREFIX="TaskExecutor";
  17. @Bean("executor")
  18. public Executor executor(){
  19. ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
  20. //核心线程数
  21. executor.setCorePoolSize(CORE_POOL_SIZE);
  22. //最大线程数
  23. executor.setMaxPoolSize(MAX_POOL_SIZE);
  24. //允许线程的空闲时间
  25. executor.setKeepAliveSeconds(KEEPALIVE_SECONDS);
  26. //缓冲队列
  27. executor.setQueueCapacity(QUERY_CAPACITY);
  28. //线程的前缀
  29. executor.setThreadNamePrefix(THREAD_NAME_PREFIX);
  30. //设置线程中任务的等待时间
  31. executor.setAwaitTerminationMillis(AVAIL_TERMINATION_MILLIS);
  32. //线程对拒绝任务的处理策略
  33. executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
  34. //线程关闭的时候等待所有任务都完成后再继续销毁其他的bean
  35. executor.setWaitForTasksToCompleteOnShutdown(true);
  36. return executor;
  37. }
  38. }

3、编写异步线程方法

  1. package com.example.task.service;
  2. import org.springframework.scheduling.annotation.Async;
  3. import org.springframework.scheduling.annotation.AsyncResult;
  4. import org.springframework.stereotype.Service;
  5. import java.util.concurrent.Future;
  6. @Service
  7. public class ExecutorTaskService {
  8. @Async("executor")
  9. public Future<String> messages1(){
  10. System.out.println("我是number one");
  11. return new AsyncResult<>("");
  12. }
  13. @Async("executor")
  14. public Future<String> messages2(){
  15. System.out.println("我是number two");
  16. return new AsyncResult<>("");
  17. }
  18. @Async("executor")
  19. public Future<String> messages3(){
  20. System.out.println("我是number three");
  21. return new AsyncResult<>("");
  22. }
  23. }

4、编写控制类,调用异步方法

  1. package com.example.task.controller;
  2. import com.example.task.service.ExecutorTaskService;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. import org.springframework.web.bind.annotation.RestController;
  6. @RestController
  7. public class ExecutorController {
  8. @Autowired
  9. ExecutorTaskService executorTaskService;
  10. @RequestMapping("/task")
  11. public void getMessage(){
  12. System.err.println("=====================");
  13. executorTaskService.messages1();
  14. executorTaskService.messages2();
  15. executorTaskService.messages3();
  16. }
  17. }

5、运行程序,对getMessage()方法进行多次访问,得到的结果如下
在这里插入图片描述

会发现getMessage()方法内调用的三个异步方法不是按顺序输出的,证明异步调动生效

这里我是用的很简单的例子来说明@Async是如何使用的,理解用法即可

发表评论

表情:
评论列表 (有 0 条评论,30人围观)

还没有评论,来说两句吧...

相关阅读