当前位置:

首页 > 编程开发 > SpringBoot怎么使用Schedule实现定时任务

SpringBoot怎么使用Schedule实现定时任务

0.开发环境IDE:IntelliJIDEA2017.1x64jdk:1.8.0_91SpringBoot:2.1.1.RELEASE1.简单定时任务对于一些比较简单的定时任务,比如固定时间间隔执行固定方法,在标准Java方法上注解@Scheduled即可packagecn.wbnull.springbootdemo.schedule;importcn.wbnull.springbootdemo.util.DateUtils;importcn.wbnull.springbootdemo.util.Logg

本文目录

      0. 开发环境

      IDE:IntelliJ IDEA 2017.1 x64

      jdk:1.8.0_91

      Spring Boot:2.1.1.RELEASE

      1. 简单定时任务

      对于一些比较简单的定时任务,比如固定时间间隔执行固定方法,在标准Java方法上注解@Scheduled即可

      package cn.wbnull.springbootdemo.schedule;
      
      import cn.wbnull.springbootdemo.util.DateUtils;
      import cn.wbnull.springbootdemo.util.LoggerUtils;
      import org.springframework.scheduling.annotation.Scheduled;
      import org.springframework.stereotype.Component;
      
      @Component
      public class ScheduledTask {
      
          @Scheduled(cron = "0/10 * * * * ?") //每10秒执行一次
          public void scheduledTaskByCorn() {
              LoggerUtils.info("定时任务开始 ByCorn:" + DateUtils.dateFormat());
              scheduledTask();
              LoggerUtils.info("定时任务结束 ByCorn:" + DateUtils.dateFormat());
          }
      
          @Scheduled(fixedRate = 10000) //每10秒执行一次
          public void scheduledTaskByFixedRate() {
              LoggerUtils.info("定时任务开始 ByFixedRate:" + DateUtils.dateFormat());
              scheduledTask();
              LoggerUtils.info("定时任务结束 ByFixedRate:" + DateUtils.dateFormat());
          }
      
          @Scheduled(fixedDelay = 10000) //每10秒执行一次
          public void scheduledTaskByFixedDelay() {
              LoggerUtils.info("定时任务开始 ByFixedDelay:" + DateUtils.dateFormat());
              scheduledTask();
              LoggerUtils.info("定时任务结束 ByFixedDelay:" + DateUtils.dateFormat());
          }
      
          private void scheduledTask() {
              try {
                  Thread.sleep(5000);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
      }

      然后项目启动类上增加注解@EnableScheduling,表示开启定时任务

      package cn.wbnull.springbootdemo;
      
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.scheduling.annotation.EnableScheduling;
      
      @SpringBootApplication
      @EnableScheduling
      public class SpringBootDemoApplication {
      
          public static void main(String[] args) {
              SpringApplication.run(SpringBootDemoApplication.class, args);
          }
      }

      这里因为我们在ScheduledTask类创建了三个定时任务,@Scheduled默认是不并发执行的,因此我们先注释掉其他,分别进行测试。

      1.1 @Scheduled(cron = “0/10 * * * * ?”)

      package cn.wbnull.springbootdemo.schedule;
      
      import cn.wbnull.springbootdemo.util.DateUtils;
      import cn.wbnull.springbootdemo.util.LoggerUtils;
      import org.springframework.scheduling.annotation.Scheduled;
      import org.springframework.stereotype.Component;
      
      @Component
      public class ScheduledTask {
      
          @Scheduled(cron = "0/10 * * * * ?") //每10秒执行一次
          public void scheduledTaskByCorn() {
              LoggerUtils.info("定时任务开始 ByCorn:" + DateUtils.dateFormat());
              scheduledTask();
              LoggerUtils.info("定时任务结束 ByCorn:" + DateUtils.dateFormat());
          }
      
          private void scheduledTask() {
              try {
                  Thread.sleep(5000);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
      }

      启动项目,运行结果如下

      [INFO][2019-02-18 16:08:40,095]||定时任务开始 ByCorn:2019-02-18 16:08:40
      [INFO][2019-02-18 16:08:45,097]||定时任务结束 ByCorn:2019-02-18 16:08:45
      [INFO][2019-02-18 16:08:50,001]||定时任务开始 ByCorn:2019-02-18 16:08:50
      [INFO][2019-02-18 16:08:55,003]||定时任务结束 ByCorn:2019-02-18 16:08:55
      [INFO][2019-02-18 16:09:00,002]||定时任务开始 ByCorn:2019-02-18 16:09:00
      [INFO][2019-02-18 16:09:05,004]||定时任务结束 ByCorn:2019-02-18 16:09:05
      [INFO][2019-02-18 16:09:10,001]||定时任务开始 ByCorn:2019-02-18 16:09:10
      [INFO][2019-02-18 16:09:15,003]||定时任务结束 ByCorn:2019-02-18 16:09:15
      [INFO][2019-02-18 16:09:20,001]||定时任务开始 ByCorn:2019-02-18 16:09:20
      [INFO][2019-02-18 16:09:25,002]||定时任务结束 ByCorn:2019-02-18 16:09:25
      [INFO][2019-02-18 16:09:30,001]||定时任务开始 ByCorn:2019-02-18 16:09:30
      [INFO][2019-02-18 16:09:35,002]||定时任务结束 ByCorn:2019-02-18 16:09:35

      我们再改下scheduledTask方法中线程休眠时间,使休眠时间大于定时任务间隔时间Thread.sleep(12000);,然后启动项目,查看运行结果。

      [INFO][2019-02-18 16:14:20,080]||定时任务开始 ByCorn:2019-02-18 16:14:20
      [INFO][2019-02-18 16:14:32,081]||定时任务结束 ByCorn:2019-02-18 16:14:32
      [INFO][2019-02-18 16:14:40,001]||定时任务开始 ByCorn:2019-02-18 16:14:40
      [INFO][2019-02-18 16:14:52,002]||定时任务结束 ByCorn:2019-02-18 16:14:52
      [INFO][2019-02-18 16:15:00,000]||定时任务开始 ByCorn:2019-02-18 16:15:00
      [INFO][2019-02-18 16:15:12,002]||定时任务结束 ByCorn:2019-02-18 16:15:12

      我们可以看到,对于cron表达式 来说,如果业务代码执行时间小于定时任务间隔时间,那么定时任务每10秒执行一次,且不受业务代码影响,无论业务代码执行多久,定时任务都是10秒执行一次;

      如果业务代码执行时间大于定时任务间隔时间,因定时任务默认不并发,所以一直到业务代码执行完成的那个10秒,定时任务也是整10秒执行一次,不受业务代码影响。

      注意:@Scheduled(cron = “0/10 * * * * ?”)控制的每10秒执行一次的定时任务,是每10秒整执行一次,即一分钟内,如果当前秒数能够整除10,则执行定时任务,或理解为每分钟0秒开始执行,10秒后执行下一次,执行完一分钟后,再从0秒开始。即只会在10s,20s,30s…的时候执行,如果配置定时任务@Scheduled(cron = “0/7 * * * * ?”)这种,则只会在0s,7s,14s…的时候执行。

      1.2 @Scheduled(fixedRate = 10000)

      package cn.wbnull.springbootdemo.schedule;
      
      import cn.wbnull.springbootdemo.util.DateUtils;
      import cn.wbnull.springbootdemo.util.LoggerUtils;
      import org.springframework.scheduling.annotation.Scheduled;
      import org.springframework.stereotype.Component;
      
      @Component
      public class ScheduledTask {
      
          @Scheduled(fixedRate = 10000) //每10秒执行一次
          public void scheduledTaskByFixedRate() {
              LoggerUtils.info("定时任务开始 ByFixedRate:" + DateUtils.dateFormat());
              scheduledTask();
              LoggerUtils.info("定时任务结束 ByFixedRate:" + DateUtils.dateFormat());
          }
      
          private void scheduledTask() {
              try {
                  Thread.sleep(12000);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
      }

      启动项目,运行结果如下

      [INFO][2019-02-18 17:33:18,235]||定时任务开始 ByFixedRate:2019-02-18 17:33:18
      [INFO][2019-02-18 17:33:23,239]||定时任务结束 ByFixedRate:2019-02-18 17:33:23
      [INFO][2019-02-18 17:33:28,191]||定时任务开始 ByFixedRate:2019-02-18 17:33:28
      [INFO][2019-02-18 17:33:33,195]||定时任务结束 ByFixedRate:2019-02-18 17:33:33
      [INFO][2019-02-18 17:33:38,189]||定时任务开始 ByFixedRate:2019-02-18 17:33:38
      [INFO][2019-02-18 17:33:43,191]||定时任务结束 ByFixedRate:2019-02-18 17:33:43
      [INFO][2019-02-18 17:33:48,184]||定时任务开始 ByFixedRate:2019-02-18 17:33:48
      [INFO][2019-02-18 17:33:53,186]||定时任务结束 ByFixedRate:2019-02-18 17:33:53
      [INFO][2019-02-18 17:33:58,190]||定时任务开始 ByFixedRate:2019-02-18 17:33:58
      [INFO][2019-02-18 17:34:03,193]||定时任务结束 ByFixedRate:2019-02-18 17:34:03

      我们再改下scheduledTask方法中线程休眠时间,使休眠时间大于定时任务间隔时间Thread.sleep(12000);,然后启动项目,查看运行结果。

      [INFO][2019-02-18 17:31:30,122]||定时任务开始 ByFixedRate:2019-02-18 17:31:30
      [INFO][2019-02-18 17:31:42,122]||定时任务结束 ByFixedRate:2019-02-18 17:31:42
      [INFO][2019-02-18 17:31:42,123]||定时任务开始 ByFixedRate:2019-02-18 17:31:42
      [INFO][2019-02-18 17:31:54,123]||定时任务结束 ByFixedRate:2019-02-18 17:31:54
      [INFO][2019-02-18 17:31:54,124]||定时任务开始 ByFixedRate:2019-02-18 17:31:54
      [INFO][2019-02-18 17:32:06,127]||定时任务结束 ByFixedRate:2019-02-18 17:32:06
      [INFO][2019-02-18 17:32:06,127]||定时任务开始 ByFixedRate:2019-02-18 17:32:06
      [INFO][2019-02-18 17:32:18,134]||定时任务结束 ByFixedRate:2019-02-18 17:32:18

      对于fixedRate 来说,如果业务代码执行时间小于定时任务间隔时间,那么定时任务每10秒执行一次,且不受业务代码影响,无论业务代码执行多久,定时任务都是10秒执行一次;

      如果业务代码执行时间大于定时任务间隔时间,则定时任务循环执行。

      1.3 @Scheduled(fixedDelay = 10000)

      package cn.wbnull.springbootdemo.schedule;
      
      import cn.wbnull.springbootdemo.util.DateUtils;
      import cn.wbnull.springbootdemo.util.LoggerUtils;
      import org.springframework.scheduling.annotation.Scheduled;
      import org.springframework.stereotype.Component;
      
      @Component
      public class ScheduledTask {
      
          @Scheduled(fixedDelay = 10000) //每10秒执行一次
          public void scheduledTaskByFixedDelay() {
              LoggerUtils.info("定时任务开始 ByFixedDelay:" + DateUtils.dateFormat());
              scheduledTask();
              LoggerUtils.info("定时任务结束 ByFixedDelay:" + DateUtils.dateFormat());
          }
      
          private void scheduledTask() {
              try {
                  Thread.sleep(5000);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
      }

      启动项目,运行结果如下

      [INFO][2019-02-18 17:45:30,784]||定时任务开始 ByFixedDelay:2019-02-18 17:45:30
      [INFO][2019-02-18 17:45:35,792]||定时任务结束 ByFixedDelay:2019-02-18 17:45:35
      [INFO][2019-02-18 17:45:45,803]||定时任务开始 ByFixedDelay:2019-02-18 17:45:45
      [INFO][2019-02-18 17:45:50,812]||定时任务结束 ByFixedDelay:2019-02-18 17:45:50
      [INFO][2019-02-18 17:46:00,814]||定时任务开始 ByFixedDelay:2019-02-18 17:46:00
      [INFO][2019-02-18 17:46:05,817]||定时任务结束 ByFixedDelay:2019-02-18 17:46:05
      [INFO][2019-02-18 17:46:15,821]||定时任务开始 ByFixedDelay:2019-02-18 17:46:15
      [INFO][2019-02-18 17:46:20,825]||定时任务结束 ByFixedDelay:2019-02-18 17:46:20
      [INFO][2019-02-18 17:46:30,829]||定时任务开始 ByFixedDelay:2019-02-18 17:46:30
      [INFO][2019-02-18 17:46:35,834]||定时任务结束 ByFixedDelay:2019-02-18 17:46:35

      我们再改下scheduledTask方法中线程休眠时间,使休眠时间大于定时任务间隔时间Thread.sleep(12000);,然后启动项目,查看运行结果。

      [INFO][2019-02-18 17:47:06,871]||定时任务开始 ByFixedDelay:2019-02-18 17:47:06
      [INFO][2019-02-18 17:47:18,879]||定时任务结束 ByFixedDelay:2019-02-18 17:47:18
      [INFO][2019-02-18 17:47:28,890]||定时任务开始 ByFixedDelay:2019-02-18 17:47:28
      [INFO][2019-02-18 17:47:40,896]||定时任务结束 ByFixedDelay:2019-02-18 17:47:40
      [INFO][2019-02-18 17:47:50,903]||定时任务开始 ByFixedDelay:2019-02-18 17:47:50
      [INFO][2019-02-18 17:48:02,911]||定时任务结束 ByFixedDelay:2019-02-18 17:48:02
      [INFO][2019-02-18 17:48:12,917]||定时任务开始 ByFixedDelay:2019-02-18 17:48:12
      [INFO][2019-02-18 17:48:24,924]||定时任务结束 ByFixedDelay:2019-02-18 17:48:24

      对于fixedDelay 来说,不管业务代码执行时间与定时任务间隔时间熟长熟短,定时任务都会等业务代码执行完成后再开启新一轮定时。

      不过,一般大家在使用定时任务时,都是定时任务时间间隔大于业务代码执行时间。

      1.4 多说一点

      对于固定时间执行的定时任务,比如每天凌晨4点执行,只能使用cron表达式的方式

      2. corn表达式

      2.1 corn表达式格式

      corn表达式格式:秒 分 时 日 月 星期 年(可选)

      字段名允许的值允许的特殊字符
      秒0-59, - * /
      分0-59, - * /
      时0-23, - * /
      日1-31, - * ? / L W C
      月1-12 或 JAN-DEC, - * /
      星期1-7 或 SUN-SAT, - * ? / L C #
      年(可选)空 或 1970-2099, - * /

      释义:

      1、*:通配符,表示该字段可以接收任意值。

      2、? :表示不确定的值,或不关心它为何值,仅在日期和星期中使用,当其中一个设置了条件时,另外一个用"?" 来表示"任何值"。

      3、,:表示多个值,附加一个生效的值。

      4、-:表示一个指定的范围

      5、/:指定一个值的增量值。例n/m表示从n开始,每次增加m

      6、L:用在日期表示当月的最后一天,用在星期"L"单独使用时就等于"7"或"SAT",如果和数字联合使用表示该月最后一个星期X。例如,"0L"表示该月最后一个星期日。

      7、W:指定离给定日期最近的工作日(周一到周五),可以用"LW"表示该月最后一个工作日。例如,"10W"表示这个月离10号最近的工作日

      8、C:表示和calendar联系后计算过的值。例如:用在日期中,"5C"表示该月第5天或之后包括calendar的第一天;用在星期中,"5C"表示这周四或之后包括calendar的第 一天。

      9、#:表示该月第几个星期X。例6#3表示该月第三个周五。

      2.2 示例值

      0 * * * * ? 每分钟触发

      0 0 * * * ? 每小时整触发

      0 0 4 * * ? 每天凌晨4点触发

      0 15 10 * * ? 每天早上10:15触发

      */5 * * * * ? 每隔5秒触发

      0 */5 * * * ? 每隔5分钟触发

      0 0 4 1 * ? 每月1号凌晨4点触发

      0 0 4 L * ? 每月最后一天凌晨3点触发

      0 0 3 ? * L 每周星期六凌晨3点触发

      0 11,22,33 * * * ? 每小时11分、22分、33分触发

      3. 配置定时任务

      对于上面那些简单的定时任务,定时任务的corn表达式写死在代码里,如果要改动表达式,需要修改代码,重新打包发布,比较麻烦。因此,我们可以把corn表达式配置在配置文件中,然后程序读取配置,当需要修改表达式时,只需要修改配置文件即可。

      application.yml增加配置

      demo:
        corn: 0/11 * * * * ?

      定时任务

      package cn.wbnull.springbootdemo.schedule;
      
      import cn.wbnull.springbootdemo.util.DateUtils;
      import cn.wbnull.springbootdemo.util.LoggerUtils;
      import org.springframework.scheduling.annotation.Scheduled;
      import org.springframework.stereotype.Component;
      
      @Component
      public class ScheduledTask {
      
          @Scheduled(cron = "${demo.corn}")
          public void scheduledTaskByConfig() {
              LoggerUtils.info("定时任务 ByConfig:" + DateUtils.dateFormat());
          }
      }

      启动项目,运行结果如下

      [INFO][2019-02-18 23:47:33,047]||定时任务 ByConfig:2019-02-18 23:47:33
      [INFO][2019-02-18 23:47:44,003]||定时任务 ByConfig:2019-02-18 23:47:44
      [INFO][2019-02-18 23:47:55,009]||定时任务 ByConfig:2019-02-18 23:47:55
      [INFO][2019-02-18 23:48:00,008]||定时任务 ByConfig:2019-02-18 23:48:00
      [INFO][2019-02-18 23:48:11,009]||定时任务 ByConfig:2019-02-18 23:48:11
      [INFO][2019-02-18 23:48:22,009]||定时任务 ByConfig:2019-02-18 23:48:22
      [INFO][2019-02-18 23:48:33,009]||定时任务 ByConfig:2019-02-18 23:48:33

      修改application.yml配置

      demo:
        corn: 0/23 * * * * ?

      启动项目,运行结果如下

      [INFO][2019-02-18 23:52:23,089]||定时任务 ByConfig:2019-02-18 23:52:23
      [INFO][2019-02-18 23:52:46,008]||定时任务 ByConfig:2019-02-18 23:52:46
      [INFO][2019-02-18 23:53:00,009]||定时任务 ByConfig:2019-02-18 23:53:00
      [INFO][2019-02-18 23:53:23,002]||定时任务 ByConfig:2019-02-18 23:53:23
      [INFO][2019-02-18 23:53:46,009]||定时任务 ByConfig:2019-02-18 23:53:46

      定时任务根据配置文件动态变化。

      4. 动态修改定时任务

      对于有些情况,我们需要在代码中,通过方法动态修改定时任务corn表达式

      application.yml配置

      demo:
        corn: 0/7 * * * * ?
        cornV2: 0/22 * * * * ?

      新建ScheduledTaskV2.java

      package cn.wbnull.springbootdemo.schedule;
      
      import cn.wbnull.springbootdemo.util.DateUtils;
      import cn.wbnull.springbootdemo.util.LoggerUtils;
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.scheduling.annotation.SchedulingConfigurer;
      import org.springframework.scheduling.config.ScheduledTaskRegistrar;
      import org.springframework.scheduling.support.CronTrigger;
      import org.springframework.stereotype.Component;
      
      @Component
      public class ScheduledTaskV2 implements SchedulingConfigurer {
      
          @Value("${demo.corn}")
          private String corn;
          @Value("${demo.cornV2}")
          private String cornV2;
      
          private int tag = 0;
      
          @Override
          public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
              scheduledTaskRegistrar.addTriggerTask(() -> {
                  LoggerUtils.info("定时任务V2:" + DateUtils.dateFormat());
              }, (triggerContext) -> {
                  CronTrigger cronTrigger;
                  if (tag % 2 == 0) {
                      LoggerUtils.info("定时任务V2动态修改corn表达式:" + corn + "," + DateUtils.dateFormat());
                      cronTrigger = new CronTrigger(corn);
                      tag++;
                  } else {
                      LoggerUtils.info("定时任务V2动态修改corn表达式:" + cornV2 + "," + DateUtils.dateFormat());
                      cronTrigger = new CronTrigger(cornV2);
                      tag++;
                  }
      
                  return cronTrigger.nextExecutionTime(triggerContext);
              });
          }
      }

      启动项目,运行结果如下

      [INFO][2019-02-19 00:19:49,011]||定时任务V2:2019-02-19 00:19:49
      [INFO][2019-02-19 00:19:49,011]||定时任务V2动态修改corn表达式:0/22 * * * * ?,2019-02-19 00:19:49
      [INFO][2019-02-19 00:20:00,007]||定时任务V2:2019-02-19 00:20:00
      [INFO][2019-02-19 00:20:00,007]||定时任务V2动态修改corn表达式:0/7 * * * * ?,2019-02-19 00:20:00
      [INFO][2019-02-19 00:20:07,006]||定时任务V2:2019-02-19 00:20:07
      [INFO][2019-02-19 00:20:07,006]||定时任务V2动态修改corn表达式:0/22 * * * * ?,2019-02-19 00:20:07
      [INFO][2019-02-19 00:20:22,008]||定时任务V2:2019-02-19 00:20:22
      [INFO][2019-02-19 00:20:22,008]||定时任务V2动态修改corn表达式:0/7 * * * * ?,2019-02-19 00:20:22
      [INFO][2019-02-19 00:20:28,010]||定时任务V2:2019-02-19 00:20:28
      [INFO][2019-02-19 00:20:28,010]||定时任务V2动态修改corn表达式:0/22 * * * * ?,2019-02-19 00:20:28
      [INFO][2019-02-19 00:20:44,003]||定时任务V2:2019-02-19 00:20:44
      [INFO][2019-02-19 00:20:44,003]||定时任务V2动态修改corn表达式:0/7 * * * * ?,2019-02-19 00:20:44
      [INFO][2019-02-19 00:20:49,004]||定时任务V2:2019-02-19 00:20:49
      [INFO][2019-02-19 00:20:49,004]||定时任务V2动态修改corn表达式:0/22 * * * * ?,2019-02-19 00:20:49
      [INFO][2019-02-19 00:21:00,011]||定时任务V2:2019-02-19 00:21:00
      [INFO][2019-02-19 00:21:00,011]||定时任务V2动态修改corn表达式:0/7 * * * * ?,2019-02-19 00:21:00
      [INFO][2019-02-19 00:21:07,011]||定时任务V2:2019-02-19 00:21:07
      [INFO][2019-02-19 00:21:07,011]||定时任务V2动态修改corn表达式:0/22 * * * * ?,2019-02-19 00:21:07

      成功通过代码动态修改corn表达式且运行结果正确。

      5. 并发执行定时任务

      回到我们 1. 简单定时任务 中创建的三个定时任务,当时因为@Scheduled默认是不并发执行的,所以我们先注释掉了其他定时任务,分别进行的测试。

      那我们实际开发中,确实创建了多个定时任务,且想并发执行时,该怎么做呢?

      定时任务类添加注解@EnableAsync,需并发执行的定时任务方法添加注解@Async

      新建定时任务类ScheduledTaskV3

      package cn.wbnull.springbootdemo.schedule;
      
      import cn.wbnull.springbootdemo.util.DateUtils;
      import cn.wbnull.springbootdemo.util.LoggerUtils;
      import org.springframework.scheduling.annotation.Async;
      import org.springframework.scheduling.annotation.EnableAsync;
      import org.springframework.scheduling.annotation.Scheduled;
      import org.springframework.stereotype.Component;
      
      @Component
      @EnableAsync
      public class ScheduledTaskV3 {
      
          @Scheduled(cron = "0/7 * * * * ?")
          @Async
          public void scheduledTaskV1() {
              LoggerUtils.info("定时任务V3,定时任务1开始:" + DateUtils.dateFormat());
              scheduledTask();
              LoggerUtils.info("定时任务V3,定时任务1结束:" + DateUtils.dateFormat());
          }
      
          @Scheduled(cron = "0/10 * * * * ?")
          @Async
          public void scheduledTaskV2() {
              LoggerUtils.info("定时任务V3,定时任务2开始:" + DateUtils.dateFormat());
              scheduledTask();
              LoggerUtils.info("定时任务V3,定时任务2结束:" + DateUtils.dateFormat());
          }
      
          @Scheduled(cron = "0/22 * * * * ?")
          @Async
          public void scheduledTaskV3() {
              LoggerUtils.info("定时任务V3,定时任务3开始:" + DateUtils.dateFormat());
              scheduledTask();
              LoggerUtils.info("定时任务V3,定时任务3结束:" + DateUtils.dateFormat());
          }
      
          private void scheduledTask() {
              try {
                  Thread.sleep(5000);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
      }

      启动项目,运行结果如下

      [INFO][2019-02-19 00:36:21,077]||定时任务V3,定时任务1开始:2019-02-19 00:36:21
      [INFO][2019-02-19 00:36:22,003]||定时任务V3,定时任务3开始:2019-02-19 00:36:22
      [INFO][2019-02-19 00:36:26,078]||定时任务V3,定时任务1结束:2019-02-19 00:36:26
      [INFO][2019-02-19 00:36:27,006]||定时任务V3,定时任务3结束:2019-02-19 00:36:27
      [INFO][2019-02-19 00:36:28,003]||定时任务V3,定时任务1开始:2019-02-19 00:36:28
      [INFO][2019-02-19 00:36:30,003]||定时任务V3,定时任务2开始:2019-02-19 00:36:30
      [INFO][2019-02-19 00:36:33,003]||定时任务V3,定时任务1结束:2019-02-19 00:36:33
      [INFO][2019-02-19 00:36:35,004]||定时任务V3,定时任务1开始:2019-02-19 00:36:35
      [INFO][2019-02-19 00:36:35,005]||定时任务V3,定时任务2结束:2019-02-19 00:36:35
      [INFO][2019-02-19 00:36:40,003]||定时任务V3,定时任务2开始:2019-02-19 00:36:40
      [INFO][2019-02-19 00:36:40,005]||定时任务V3,定时任务1结束:2019-02-19 00:36:40
      [INFO][2019-02-19 00:36:42,001]||定时任务V3,定时任务1开始:2019-02-19 00:36:42
      [INFO][2019-02-19 00:36:44,003]||定时任务V3,定时任务3开始:2019-02-19 00:36:44
      [INFO][2019-02-19 00:36:45,004]||定时任务V3,定时任务2结束:2019-02-19 00:36:45
      [INFO][2019-02-19 00:36:47,002]||定时任务V3,定时任务1结束:2019-02-19 00:36:47
      [INFO][2019-02-19 00:36:49,002]||定时任务V3,定时任务1开始:2019-02-19 00:36:49
      [INFO][2019-02-19 00:36:49,004]||定时任务V3,定时任务3结束:2019-02-19 00:36:49
      [INFO][2019-02-19 00:36:50,001]||定时任务V3,定时任务2开始:2019-02-19 00:36:50

      定时任务能够并发执行。

      本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
      作者最新文章
      编程开发 Schedule
      相关文章 更多
      springBoot项目常用目录有哪些
      springBoot项目常用目录有哪些

      springBoot项目常用目录springBoot项目的目录结构及名规范介绍基于SpringBoot开发时的目录结构及命名规范,通过介绍能够为你解决,在实际项目中如何规划目录结构?如何命名目录更规范?各个目录分别代表什么含义?等三个问题。目录说明servicex//项目名|-admin-ui//管理服务前端代码(一般将UI和SERVICE放到一个工程中,便于管理)|-servicex-auth//模块1|-servicex-common//模块2|-servicex-gateway//模块3|-serv

      解析SpringBoot和SpringMVC之间的异同
      解析SpringBoot和SpringMVC之间的异同

      解析SpringBoot和SpringMVC之间的异同SpringBoot和SpringMVC是Java领域中非常重要的开发框架。虽然它们都属于Spring框架的一部分,但是在使用和功能上有一些明显的区别。本文将对SpringBoot和SpringMVC进行比较,解析它们之间的异同。首先,让我们来了解一下SpringBoot。SpringBo

      探索SpringCloud和SpringBoot在微服务领域的不同应用方式
      探索SpringCloud和SpringBoot在微服务领域的不同应用方式

      近年来,随着云计算和分布式架构的兴起,微服务架构的应用越来越广泛。而SpringCloud和SpringBoot作为Java开发中的两个重要框架,对于微服务的实现起到了重要的作用。然而,很多人对于它们在微服务领域的不同应用方式还存在一定的疑惑。本文将从不同的角度探索SpringCloud和SpringBoot在微服务中的应用方式。首先,我们来了解一下Spri

      SpringBoot和SpringMVC有何区别?
      SpringBoot和SpringMVC有何区别?

      SpringBoot与SpringMVC的不同之处在哪里?SpringBoot和SpringMVC是两个非常流行的Java开发框架,用于构建Web应用程序。尽管它们经常分别被使用,但它们之间的不同之处也是很明显的。首先,SpringBoot可以被看作是一个Spring框架的扩展或者增强版。它旨在简化Spring应用程序的初始化和配置过程,以帮助开发人

      比较SpringBoot和SpringMVC的异同
      比较SpringBoot和SpringMVC的异同

      SpringBoot和SpringMVC都是Java开发中常用的框架,但它们之间有一些明显的差异。本文将探究这两个框架的特点和用途,并对它们的差异进行比较。首先,我们来了解一下SpringBoot。SpringBoot是由Pivotal团队开发的,它旨在简化基于Spring框架的应用程序的创建和部署。它提供了一种快速、轻量级的方式来构建独立的、可执行

      SpringBoot与SpringMVC的不同点是什么?
      SpringBoot与SpringMVC的不同点是什么?

      SpringBoot和SpringMVC是Java开发中常用的两个框架,它们都是由Spring框架所提供的,但在功能和使用方式上有着一些区别。本文将分别介绍SpringBoot和SpringMVC的特点和区别。一、SpringBoot的特点:简化配置:SpringBoot通过约定优于配置的原则,大大简化了项目的配置过程。它可以自动配置项目所需要的参数,开发人

      比较和选择指南:SpringCloud与SpringBoot的功能比较
      比较和选择指南:SpringCloud与SpringBoot的功能比较

      SpringCloud和SpringBoot是目前Java领域中最热门的开源框架,它们分别提供了一套完善的微服务架构和快速构建应用程序的解决方案。本文将对它们的功能进行比较,并给出选择指南,以帮助读者了解它们的优势和适用场景。SpringBoot是一个用于开发Java应用程序的框架,它提供了一个简化的开发流程,集成了大量常用的功能和组件,减少了开发者的工作量

      SpringCloud与SpringBoot:分析它们之间的相似与不同
      SpringCloud与SpringBoot:分析它们之间的相似与不同

      深入剖析SpringCloud和SpringBoot的异同引言:在构建企业级应用程序时,Spring框架已经成为开发者们的首选。它提供了一种简单而强大的方式来构建独立于平台的应用程序。Spring框架由两个核心模块组成:SpringBoot和SpringCloud。虽然它们都可以帮助开发者快速搭建应用程序,但它们的目标和用途存在一些差异。本文将深入剖析Spr

      从架构角度看SpringCloud与SpringBoot的差异
      从架构角度看SpringCloud与SpringBoot的差异

      从架构角度看SpringCloud与SpringBoot的差异引言:在当今的互联网时代,构建分布式系统已经成为了一种必要的需求。而SpringBoot和SpringCloud正是为了满足这个需求而诞生的。尽管它们都是由Spring框架所提供的解决方案,但从架构角度来看,它们存在着一些重要的差异。本文将从架构的角度出发,对SpringBoot和SpringCl

      Java API 开发中使用 SpringBoot 的利弊分析
      Java API 开发中使用 SpringBoot 的利弊分析

      JavaAPI开发中使用SpringBoot的利弊分析随着互联网的快速发展和技术的不断更新迭代,Java技术在开发中的广泛应用引起了人们的重视。而SpringBoot作为一种微服务架构的解决方案,已经逐渐成为Java开发中的热门选择。那么,在JavaAPI开发中使用SpringBoot,到底有哪些利弊呢?下面来分析一下。利:简化开发

      查看更多
      精品专题 更多
      装机必备
      装机必备

      正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

      Windows
      Windows

      正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

      PDF教程
      PDF教程

      正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

      Mac软件 更多
      讯飞智作 网页版
      讯飞智作 网页版
      Windows/ macOS/ Linux

      讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

      火山引擎 网页版
      火山引擎 网页版
      Windows/ macOS/ Linux

      火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

      Aperty macOS版
      Aperty macOS版
      macOS

      Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

      WINDOWS 更多
      讯飞智作 网页版
      讯飞智作 网页版
      Windows/ macOS/ Linux

      讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

      火山引擎 网页版
      火山引擎 网页版
      Windows/ macOS/ Linux

      火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

      PixTV 网页版
      PixTV 网页版
      Windows

      PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。