gpt4 book ai didi

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

转载 作者:qq735679552 更新时间:2022-09-28 22:32:09 45 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章Spring @Scheduler使用cron表达式时的执行问题详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

前言 。

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

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

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

  • 同一定时任务,第二次触发时间到了,第一次还没有执行完成时会执行吗?
  • 不同的定时任务,相互之间是否有影响?

结论写在前面:

  • 同一定时任务,第二次触发时间到了,第一次还没有执行完成时会执行吗?不会,会等前一次执行完成才执行下一次
  • 不同的定时任务,相互之间是否有影响?取决于可用的定时任务线程数,如果线程数足够则不会影响;如果可用定时任务线程数少于要执行定时任务数量,未能获取到线程的自然要等到有空闲线程时才能执行。

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

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

  1. 设置scheduler为多线程,设置一个线程5秒执行一次,方法体为 sleep8秒
  2. 使用scheduler默认的单线程,设置两个线程都是5秒执行一次,一个 sleep8秒,一个不sleep
  3. 设置scheduler为多线程,设置两个线程都是5秒执行一次,一个 sleep8秒,一个不sleep

实验一 。

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

?
1
2
3
4
5
@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 2017-10-11 17:49:55 scheduler-1 test1, 5秒执行一次,每次执行sleep 8 2017-10-11 17:50:05 scheduler-1 test1, 5秒执行一次,每次执行sleep 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秒执行一次,则为串行 。

?
1
2
3
4
5
6
7
8
9
10
@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, 5秒执行一次,每次执行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 。

?
1
2
3
4
5
6
7
8
9
10
@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:

?
1
2
3
4
5
6
7
8
9
10
11
@configuration
public class scheduleconfig {
 
  @bean
  public threadpooltaskscheduler threadpooltaskscheduler() {
   threadpooltaskscheduler scheduler = new threadpooltaskscheduler();
   scheduler.setpoolsize( 3 );
   scheduler.setthreadnameprefix( "scheduler-" );
   return scheduler;
  }
}

总结 。

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

原文链接:https://www.cnblogs.com/chrischennx/p/7652087.html 。

最后此篇关于Spring @Scheduler使用cron表达式时的执行问题详解的文章就讲到这里了,如果你想了解更多关于Spring @Scheduler使用cron表达式时的执行问题详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

45 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com