目次
0. 開発環境
1. 単純なスケジュールされたタスク
1.1 @Scheduled(cron = “0/10 * * * * ?”)
1.2 @Scheduled(fixedRate = 10000)
1.3 @Scheduled(fixedDelay = 10000)
1.4 多说一点
2. corn表达式
2.1 corn表达式格式
2.2 示例值
3. 配置定时任务
4. 动态修改定时任务
5. 并发执行定时任务
ホームページ Java &#&チュートリアル SpringBoot がスケジュールを使用してスケジュールされたタスクを実装する方法

SpringBoot がスケジュールを使用してスケジュールされたタスクを実装する方法

May 27, 2023 pm 08:49 PM
schedule springboot

    0. 開発環境

    IDE: IntelliJ IDEA 2017.1 x64

    jdk: 1.8.0_91

    Spring Boot :2.1.1.RELEASE

    1. 単純なスケジュールされたタスク

    一定の時間間隔で固定のメソッドを実行するなど、比較的単純なスケジュールされたタスクの場合は、標準 Java で @Scheduled アノテーションを付けるだけで済みます。 method

    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 クラスに 3 つのスケジュールされたタスクを作成しているため、@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
    [情報][2019-02-18 16:08:55,003]||時間制限付きタスクが終了しました ByCorn: 2019-02-18 16:08:55
    [情報][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); を指定し、プロジェクトを開始して実行結果を確認します。

    [情報][2019-02-18 16:14:20,080]||スケジュールされたタスクが開始されました 投稿者:2019-02-18 16:14:20
    [情報][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
    [情報][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 秒ごとに 1 回実行されます。

    ビジネス コードの実行時間ががスケジュールされたタスク間隔より大きい場合、スケジュールされたタスクはデフォルトで 同時実行性がないため、ビジネス コードの実行が完了してから 10 秒が経過するまで、スケジュールされたタスクは 10 秒ごとに実行され、ビジネス コードの影響を受けません。

    注: @Scheduled(cron = "0/10 * * * * ?") によって制御されるスケジュールされたタスクは、10 秒ごとに実行されます。つまり、現在の秒数が指定されている場合、1 分以内に実行されます。を 10 で均等に割ると、スケジュールされたタスクが実行されます。または、毎分 0 秒から開始し、10 秒後に次回実行し、1 分後に 0 秒から開始すると理解できます。つまり、10 秒、20 秒、30 秒にのみ実行されます...スケジュールされたタスク @Scheduled(cron = "0/7 * * * * ?") を設定すると、0 秒、7 秒、 14秒…。

    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();
            }
        }
    }
    ログイン後にコピー

    プロジェクトを開始すると、実行結果は次のとおりです

    [情報][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]|| スケジュールされたタスク EndByFixedRate: 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

    スケジュールされたタスクの間隔 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

    定时任务能够并发执行。

    以上がSpringBoot がスケジュールを使用してスケジュールされたタスクを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    このウェブサイトの声明
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

    ホットAIツール

    Undresser.AI Undress

    Undresser.AI Undress

    リアルなヌード写真を作成する AI 搭載アプリ

    AI Clothes Remover

    AI Clothes Remover

    写真から衣服を削除するオンライン AI ツール。

    Undress AI Tool

    Undress AI Tool

    脱衣画像を無料で

    Clothoff.io

    Clothoff.io

    AI衣類リムーバー

    AI Hentai Generator

    AI Hentai Generator

    AIヘンタイを無料で生成します。

    ホットツール

    メモ帳++7.3.1

    メモ帳++7.3.1

    使いやすく無料のコードエディター

    SublimeText3 中国語版

    SublimeText3 中国語版

    中国語版、とても使いやすい

    ゼンドスタジオ 13.0.1

    ゼンドスタジオ 13.0.1

    強力な PHP 統合開発環境

    ドリームウィーバー CS6

    ドリームウィーバー CS6

    ビジュアル Web 開発ツール

    SublimeText3 Mac版

    SublimeText3 Mac版

    神レベルのコード編集ソフト(SublimeText3)

    Springboot が Jasypt を統合して構成ファイルの暗号化を実装する方法 Springboot が Jasypt を統合して構成ファイルの暗号化を実装する方法 Jun 01, 2023 am 08:55 AM

    Jasypt の概要 Jasypt は、開発者が最小限の労力で基本的な暗号化機能を自分のプロジェクトに追加できる Java ライブラリであり、暗号化の仕組みを深く理解する必要はありません。一方向および双方向暗号化の高いセキュリティ。標準ベースの暗号化テクノロジー。パスワード、テキスト、数値、バイナリを暗号化します... Spring ベースのアプリケーション、オープン API への統合、JCE プロバイダーでの使用に適しています... 次の依存関係を追加します: com.github.ulisesbocchiojasypt-spring-boot-starter2. 1.1 Jasypt の特典はシステムのセキュリティを保護し、コードが漏洩した場合でもデータ ソースは保証されます。

    SpringBoot が Redisson を統合して遅延キューを実装する方法 SpringBoot が Redisson を統合して遅延キューを実装する方法 May 30, 2023 pm 02:40 PM

    使用シナリオ 1. 注文は正常に行われましたが、支払いが 30 分以内に行われませんでした。支払いがタイムアウトになり、注文が自動的にキャンセルされました 2. 注文に署名があり、署名後 7 日間評価が行われませんでした。注文がタイムアウトして評価されない場合、システムはデフォルトでプラスの評価を設定します 3. 注文は正常に行われます。販売者が 5 分間注文を受け取らない場合、注文はキャンセルされます。 4. 配送がタイムアウトします。 SMS リマインダーをプッシュします... 遅延が長く、リアルタイム パフォーマンスが低いシナリオでは、タスク スケジュールを使用して定期的なポーリング処理を実行できます。例: xxl-job 今日は選択します

    Redis を使用して SpringBoot に分散ロックを実装する方法 Redis を使用して SpringBoot に分散ロックを実装する方法 Jun 03, 2023 am 08:16 AM

    1. Redis は分散ロックの原則を実装しており、分散ロックが必要な理由 分散ロックについて話す前に、分散ロックが必要な理由を説明する必要があります。分散ロックの反対はスタンドアロン ロックです。マルチスレッド プログラムを作成するとき、共有変数を同時に操作することによって引き起こされるデータの問題を回避します。通常、ロックを使用して共有変数を相互に除外し、データの正確性を確保します。共有変数の使用範囲は同じプロセス内です。共有リソースを同時に操作する必要があるプロセスが複数ある場合、どうすれば相互排他的になるのでしょうか?今日のビジネス アプリケーションは通常マイクロサービス アーキテクチャであり、これは 1 つのアプリケーションが複数のプロセスをデプロイすることも意味します。複数のプロセスが MySQL の同じレコード行を変更する必要がある場合、順序の乱れた操作によって引き起こされるダーティ データを避けるために、分散が必要です。今回導入するスタイルはロックされています。ポイントを獲得したい

    Springbootがjarパッケージにファイルを読み込んだ後にファイルにアクセスできない問題を解決する方法 Springbootがjarパッケージにファイルを読み込んだ後にファイルにアクセスできない問題を解決する方法 Jun 03, 2023 pm 04:38 PM

    Springboot はファイルを読み取りますが、jar パッケージにパッケージ化した後、最新の開発にアクセスできません。jar パッケージにパッケージ化した後、Springboot がファイルを読み取れない状況があります。その理由は、パッケージ化後、ファイルの仮想パスが変更されるためです。は無効であり、ストリーム経由でのみアクセスできます。読み取ります。ファイルはリソースの下にあります publicvoidtest(){Listnames=newArrayList();InputStreamReaderread=null;try{ClassPathResourceresource=newClassPathResource("name.txt");Input

    SQL ステートメントを使用せずに Springboot+Mybatis-plus を実装して複数のテーブルを追加する方法 SQL ステートメントを使用せずに Springboot+Mybatis-plus を実装して複数のテーブルを追加する方法 Jun 02, 2023 am 11:07 AM

    Springboot+Mybatis-plus が SQL ステートメントを使用して複数テーブルの追加操作を実行しない場合、私が遭遇した問題は、テスト環境で思考をシミュレートすることによって分解されます: パラメーターを含む BrandDTO オブジェクトを作成し、パラメーターをバックグラウンドに渡すことをシミュレートします。 Mybatis-plus で複数テーブルの操作を実行するのは非常に難しいことを理解してください。Mybatis-plus-join などのツールを使用しない場合は、対応する Mapper.xml ファイルを設定し、臭くて長い ResultMap を設定するだけです。対応する SQL ステートメントを記述します。この方法は面倒に見えますが、柔軟性が高く、次のことが可能です。

    SpringBootとSpringMVCの比較と差異分析 SpringBootとSpringMVCの比較と差異分析 Dec 29, 2023 am 11:02 AM

    SpringBoot と SpringMVC はどちらも Java 開発で一般的に使用されるフレームワークですが、それらの間には明らかな違いがいくつかあります。この記事では、これら 2 つのフレームワークの機能と使用法を調べ、その違いを比較します。まず、SpringBoot について学びましょう。 SpringBoot は、Spring フレームワークに基づいたアプリケーションの作成と展開を簡素化するために、Pivo​​tal チームによって開発されました。スタンドアロンの実行可能ファイルを構築するための高速かつ軽量な方法を提供します。

    SpringBoot が Redis をカスタマイズしてキャッシュのシリアル化を実装する方法 SpringBoot が Redis をカスタマイズしてキャッシュのシリアル化を実装する方法 Jun 03, 2023 am 11:32 AM

    1. RedisAPI のデフォルトのシリアル化メカニズムである RedisTemplate1.1 をカスタマイズします。API ベースの Redis キャッシュ実装では、データ キャッシュ操作に RedisTemplate テンプレートを使用します。ここで、RedisTemplate クラスを開いて、クラスのソース コード情報を表示します。publicclassRedisTemplateextendsRedisAccessorimplementsRedisOperations、BeanClassLoaderAware{//キーを宣言、値の各種シリアル化メソッド、初期値は空 @NullableprivateRedisSe

    Springbootでapplication.ymlの値を取得する方法 Springbootでapplication.ymlの値を取得する方法 Jun 03, 2023 pm 06:43 PM

    プロジェクトでは、構成情報が必要になることがよくありますが、この情報はテスト環境と本番環境で構成が異なる場合があり、実際のビジネス状況に基づいて後で変更する必要がある場合があります。これらの構成をコードにハードコーディングすることはできません。構成ファイルに記述することをお勧めします。たとえば、この情報を application.yml ファイルに書き込むことができます。では、コード内でこのアドレスを取得または使用するにはどうすればよいでしょうか?方法は2つあります。方法 1: @Value アノテーションが付けられた ${key} を介して、構成ファイル (application.yml) 内のキーに対応する値を取得できます。この方法は、マイクロサービスが比較的少ない状況に適しています。方法 2: 実際には、プロジェクト、業務が複雑な場合、ロジック

    See all articles