浅谈SpringBoot的@Scheduled的并发问题

 

SpringBoot @Scheduled的并发

由于SpringBoot自带的@Scheduled是一个阻塞执行的定时任务,所以效率会很慢,就会造成同一个时间段内只有一个定时任务在执行,其余的就会阻塞

现有两个定时任务

@Component("aa")
public class aa {
  @Scheduled(cron = "0 44 17 * * ?")
  public void bb() {
      try {
          System.out.println("aa执行时间:" + new Date());
          Thread.sleep(65000);
          System.out.println("aa完成时间:" + new Date());
      } catch (Exception e) {
          e.printStackTrace();
      }
  }
}
@Component("bb")
public class bb {
  @Scheduled(cron = "0 55 17 * * ?")
  public void aa() {
      try {
          System.out.println("bb执行时间:" + new Date());
          Thread.sleep(10000);
          System.out.println("bb完成时间:" + new Date());
      } catch (Exception e) {
          e.printStackTrace();
      }
  }

默认的在启动项加入@EnableScheduling注解就可以运行了

在这里插入图片描述

最终,执行的结果令人大跌眼镜。

在这里插入图片描述

aa的任务由于执行时间需要65秒,超过了bb任务执行的时间,结果bb任务执行的时间被阻塞掉,延迟了5秒执行。

解决方法是在启动项类中加入如下配置即可

@Bean
  public TaskScheduler taskScheduler() {
      ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
      taskScheduler.setPoolSize(50);
      return taskScheduler;
  }

如果是xml

<!-- 注解式 -->
<task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>
<task:executor id="myExecutor" pool-size="5"/>
<task:scheduler id="myScheduler" pool-size="10"/>

 

spring @Scheduled 并发执行

spring @Scheduled ,默认基于单线程执行,如果需要基于多线程执行,需要在配置文件中配置如下

queue-capacity="500" rejection-policy="CALLER_RUNS" />
scheduler="scheduler" />

具体可以参考spring 帮助文档对annotation-driven的executor和scheduler的解释

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程宝库

 一、AOP概述AOP,即面向切面编程,简单来说就是将代码中重复的部分抽取出来,在需要执行的时候使用动态代理的技术,在不修改源码的基础上对方法进行增强;AOP也是Spring框架的一个重点,利用 ...