Spring @Scheduler使用cron表达式时的执行问题详解

网友投稿 663 2023-01-22


Spring @Scheduler使用cron表达式时的执行问题详解

前言

Spring Scheduler里有两个概念:任务(Task)和运行任务的框架(TaskExecutor/TaskScheduler)。TaskExecutor顾名思义,是任务的执行器,允许我们异步执行多个任务。TaskScheduler是任务调度器,来运行未来的定时任务。触发器Trigger可以决定定时任务是否该运行了,最常用的触发器是CronTrigger。Spring内置了多种类型的TaskExecutor和TaskScheduler,方便用户根据不同业务场景选择。

本文主要介绍了关于Spring @Scheduler使用cron表达式执行问题的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧

主要想弄清使用Spring @Scheduler cron表达式时的两个问题:

同一定时任务,第二次触发时间到了,第一次还没有执行完成时会执行吗?

不同的定时任务,相互之间是否有影响?

结论写在前面:

同一定时任务,第二次触发时间到了,第一次还没有执行完成时会执行吗?不会,会等前一次执行完成才执行下一次

不同的定时任务,相互之间是否有影响?取决于可用的定时任务线程数,如果线程数足够则不会影响;如果可用定时任务线程数少于要执行定时任务数量,未能获取到线程的自然要等到有空闲线程时才能执行。

下面是实验过程。。。。。

使用Spring @Scheduler 时,默认只有一个线程,针对上面的问题,设计了3个实验:

设置Scheduler为多线程,设置一个线程5秒执行一次,方法体为 sleep8秒

使用Scheduler默认的单线程,设置两个线程都是5秒执行一次,一个 sleep8秒,一个不sleep

设置Scheduler为多线程,设置两个线程都是5秒执行一次,一个 sleep8秒,一个不sleep

实验一

设置Scheduler为多线程,设置一个线程5秒执行一次,方法体为 sleep8秒:

@Scheduled(cron = "*/5 * * * * *")

public void test1() throws InterruptedException {

log.info("test1, 5秒执行一次,每次执行sleep 8s");

Thread.sleep(8000L);

}

结果:

2017-10-11 17:49:45 scheduler-1 test1, 5秒执行一次,每次执行sleep 8

http://2017-10-11 17:49:55 scheduler-1 test1, 5秒执行一次,每次执行sleep 8

2017-10-11 17:50:05 scheduler-1 test1, 5秒执行一次,每次执行shttp://leep 8

2017-10-11 17:50:15 scheduler-2 test1, 5秒执行一次,每次执行sleep 8

2017-10-11 17:50:25 scheduler-2 test1, 5秒执行一次,每次执行sleep 8

2017-10-11 17:50:35 scheduler-1 test1, 5秒执行一次,每次执行sleep 8

结论:

@Scheduled使用cron表达式,设置为多线程时,同一任务前一次没有执行完成,不会执行下一次

实验二

使用Scheduler默认的单线程,设置两个线程都是5秒执行一次,一个 sleep8秒,一个不sleep

如果test2每8秒执行一次,则为串行

@Scheduled(cron = "*/5 * * * * *")

public void test1() throws InterruptedException {

System.out.println("test1, 5秒执行一次,每次执行sleep 8s");

Thread.sleep(8000L);

}

@Scheduled(cron = "*/5 * * * * *")

public void test2() {

System.out.println("test2, 5秒执行一次,不sleep");

}

执行结果:

2017-10-11 17:17:35 test2, 5秒执行一次,不sleep

2017-10-11 17:17:35 test1, 5秒执行一次,每次执行sleep 8s

2017-10-11 17:17:43 test2, 5秒执行一次,不sleep

2017-10-11 17:17:45 test1, 5秒执行一次,每次执行sleep 8s

2017-10-11 17:17:53 test2, 5秒执行一次,不sleep

2017-10-11 17:17:55 test2, 5秒执行一次,不sleep

2017-10-11 17:17:55 test1, 5秒执行一次,每次执行sleep 8s

2017-10-11 17:18:03 test2, 5秒执行一次,不sleep

2017-10-11 17:18:05 test2, 5秒执行一次,不sleep

2017-10-11 17:18:05 test1, KogvkRXafc5秒执行一次,每次执行sleep 8s

2017-10-11 17:18:13 test2, 5秒执行一次,不sleep

2017-10-11 17:18:15 test1, 5秒执行一次,每次执行sleep 8s

2017-10-11 17:18:23 test2, 5秒执行一次,不sleep

2017-10-11 17:18:25 test1, 5秒执行一次,每次执行sleep 8s

对比期望执行时间:

执行次数

task

期望执行时间

实际执行时间

1

task1

17:17:35

17:17:35

1

task2

17:17:35

17:17:35

2

task1

17:17:40

17:17:43

2

task2

17:17:40

17:17:45

结论:

@Scheduled使用cron表达式 ,配置为一个线程时,不同定时任务是串行执行,且上次没有执行完时不会执行下次

实验三

设置Scheduler为多线程,设置两个线程都是5秒执行一次,一个 sleep8秒,一个不sleep

@Scheduled(cron = "*/5 * * * * *")

public void test1() throws InterruptedException {

log.info("test1, 5秒执行一次,每次执行sleep 8s");

Thread.sleep(8000L);

}

@Scheduled(cron = "*/5 * * * * *")

public void test2() {

log.info("test2, 5秒执行一次,不sleep");

}

结果:

2017-10-11 18:12:40 scheduler-2 test2, 5秒执行一次,不sleep

2017-10-11 18:12:40 scheduler-1 test1, 5秒执行一次,每次执行sleep 8s

2017-10-11 18:12:45 scheduler-2 test2, 5秒执行一次,不sleep

2017-10-11 18:12:50 scheduler-1 test1, 5秒执行一次,每次执行sleep 8s

2017-10-11 18:12:50 scheduler-2 test2, 5秒执行一次,不sleep

2017-10-11 18:12:55 scheduler-2 test2, 5秒执行一次,不sleep

2017-10-11 18:13:00 scheduler-1 test1, 5秒执行一次,每次执行sleep 8s

对比期望执行时间:

执行次数

task

期望执行时间

实际执行时间

1

task1

18:12:40

18:12:40

1

task2

18:12:40

18:12:40

2

task1

18:12:45

18:12:50

2

task2

18:12:45

18:12:45

结论:

@Scheduled使用cron表达式 ,配置为多线程时,不同定时任务不是串行执行,且上次没有执行完时不会执行下次

设置定时任务为多线程

这里用的是spring boot:

@Configuration

public class ScheduleConfig {

@Bean

public ThreadPoolTaskScheduler threadPoolTaskScheduler() {

ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();

scheduler.setPoolSize(3);

scheduler.setThreadNamePrefix("scheduler-");

return scheduler;

}

}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:mybatis注解与xml常用语句汇总
下一篇:spring boot配置读写分离的完整实现步骤
相关文章

 发表评论

暂时没有评论,来抢沙发吧~