• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

SpringBoot开启异步多线程

武飞扬头像
清泉影月
帮助3

前言:

        SpringBoot 的异步多线程需要从 java 的多线程基础说起,可以参考 java 多线程实现的三种方式区别。SpringBoot 在此基础上进行了多次封装,所以使用起来非常方便。

一、核心参数说明

        ThreadPoolExecutor 是 java 的核心线程池类;Spring 对 ThreadPoolExecutor 进行二次封装形成了 ThreadPoolTaskExecutor,其中几个核心参数除了名字略有改动,核心含义没变,下面说明一下:

  • corePoolSize:核心线程池数
  • maxPoolSize:最大线程池数
  • queueCapacity:线程池队列最大容量
  • keepAliveSeconds:允许线程的空闲时间,核心线程外的线程在空闲时间到达后会被销毁
  • threadNamePrefix:线程池名的前缀
  • rejectedExecutionHandler:拒绝策略

其中拒绝策略是线程达到某种饱和后的线程池的操作策略,总共四种:

  • AbortPolicy:如果线程池队列满了丢掉任务并且抛出RejectedExecutionException异常
  • DiscardPolicy:如果线程池队列满了,会直接丢掉这个任务并且不会抛出异常
  • DiscardOldestPolicy:如果队列满了,会将最早进入队列的任务删掉,再尝试加入队列
  • CallerRunsPolicy:如果添加到线程池失败,那么主线程会自己去执行该任务

说明一下几个核心参数和拒绝策略是怎么工作的:

1.核心线程数:m,最大线程数: n(一般 n > m),线程池队列最大容量: j,线程总数: s;

2.线程进场后(s<m),线程会直接启动直到启动的线程数达到核心线程数(s=m);

3.线程继续进场(m<s<m j),线程开始排队,此时启动的线程数不会增加直到队列饱和(s=m j);

4.线程继续进场(m j<s<n j),每进场一个线程,该线程就会启动;直到启动的线程达到最大线程数(s=n j);

5.线程继续进场(s>n j),此时触发拒绝策略;

二、使用说明

  首先配置线程池:

  1.  
    @Configuration
  2.  
    @EnableAsync
  3.  
    public class ThreadPoolConfig {
  4.  
     
  5.  
    @Bean("normalThreadPool") //线程池实例名,多个线程池配置需要声明,一个线程池可有可无
  6.  
    public Executor executorNormal() {
  7.  
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
  8.  
    executor.setCorePoolSize(3);
  9.  
    executor.setMaxPoolSize(5);
  10.  
    executor.setQueueCapacity(3);
  11.  
    executor.setKeepAliveSeconds(60);
  12.  
    executor.setThreadNamePrefix("NORMAL--");
  13.  
    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
  14.  
    executor.initialize();
  15.  
    return executor;
  16.  
    }
  17.  
    }
学新通

其次在需要异步的方法上加 @Async 注解:

  1.  
    @Slf4j
  2.  
    @Service
  3.  
    public class ThreadTaskService {
  4.  
     
  5.  
    @Async("normalThreadPool") //多个线程池配置时需指定配置实例
  6.  
    public void task() {
  7.  
    log.info("task start...");
  8.  
    try {
  9.  
    Thread.sleep(3000);
  10.  
    } catch (InterruptedException e) {
  11.  
    e.printStackTrace();
  12.  
    }
  13.  
    log.info("task end...");
  14.  
    }
  15.  
     
  16.  
    }
学新通

异步的调用跟普通 service 方法没区别:

  1.  
    @Slf4j
  2.  
    @RestController
  3.  
    @RequestMapping("/thread")
  4.  
    public class ThreadTaskController {
  5.  
     
  6.  
    @Autowired
  7.  
    ThreadTaskService taskService;
  8.  
     
  9.  
    @GetMapping(value = "/start")
  10.  
    public String getValue() {
  11.  
    taskService.task();
  12.  
    return "hello...";
  13.  
    }
  14.  
    }

三、带返回值的异步

要获取异步函数的返回值可以使用 Future,但是Future 的get方法是阻塞的,使用时需要注意。

  1.  
    @Async("normalThreadPool")
  2.  
    public CompletableFuture<String> task() {
  3.  
    String result = "000";
  4.  
    log.info("task start...");
  5.  
    try {
  6.  
    Thread.sleep(5000);
  7.  
    result = "333";
  8.  
    } catch (InterruptedException e) {
  9.  
    e.printStackTrace();
  10.  
    }
  11.  
    log.info("task end...");
  12.  
    return CompletableFuture.completedFuture(result);
  13.  
    }
  1.  
    @Slf4j
  2.  
    @RestController
  3.  
    @RequestMapping("/thread")
  4.  
    public class ThreadTaskController {
  5.  
    @Autowired
  6.  
    ThreadTaskService taskService;
  7.  
     
  8.  
    @GetMapping(value = "/start")
  9.  
    public String getValue() throws ExecutionException, InterruptedException {
  10.  
     
  11.  
    CompletableFuture<String> result = taskService.task();
  12.  
     
  13.  
    log.info("result:{}", result.get()); // get 方法会使主线程阻塞
  14.  
     
  15.  
    return "hello...";
  16.  
    }
  17.  
    }
学新通

四、几种异步失败的情况

1. 异步方法使用static关键词修饰;

2. 缺少 @EnableAsync 注解;

3. 同一个类中,一个方法调用另外一个有@Async注解的方法(原因是@Async注解的方法,是在代理类中执行的);

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfeikef
系列文章
更多 icon
同类精品
更多 icon
继续加载