Spring Boot @Scheduled 定时任务

Spring BootJavaScheduled大约 3549 字

创建定时任务

添加@EnableScheduling注解,开启定时任务支持。

@EnableScheduling
@SpringBootApplication
public class ScheduledApplication {


    public static void main(String[] args) {
        SpringApplication.run(ScheduledApplication.class, args);
    }


}

添加@Scheduled注解,开启定时任务。

@Component
public class ScheduledTask {

    @Scheduled(cron = "* * * * * ?")
    public void scheduled() throws IOException {
        System.out.println("任务执行时间:" + LocalDateTime.now());
    }

}

配置定时任务线程池

方式一(推荐)

@Bean
public TaskScheduler taskScheduler() {
    ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
    taskScheduler.setPoolSize(10);
    // 设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean
    taskScheduler.setWaitForTasksToCompleteOnShutdown(true);
    // 设置线程池中任务的等待时间,如果超过这个时候还没有销毁就强制销毁,以确保应用最后能够被关闭,而不是阻塞住
    taskScheduler.setAwaitTerminationSeconds(60);
    taskScheduler.setThreadNamePrefix("t-scheduler-");
    taskScheduler.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    return taskScheduler;
}

方式二

@Configuration
public class SchedulingConfig implements SchedulingConfigurer {

    @Bean
    public Executor taskExecutor() {
        return Executors.newScheduledThreadPool(100);
    }

    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        scheduledTaskRegistrar.setScheduler(taskExecutor());
    }

}

注解参数详解

  • @Scheduled(cron = "0 0 8 ?"):通过cron表达式定义规则,每日早上8点执行。
  • @Scheduled(fixedDelay = 1000):任务执行完毕之后延迟1秒(此处设置的是1秒)再执行下一次任务,需等待此次任务完成再延迟1秒
  • @Scheduled(fixedRate = 1000):
    • 若任务执行时间大于1秒(此处设置的是1秒),则执行结束后立即开始下一次任务
    • 若执行时间小于1秒,则每隔1秒执行
    • 如果就想要每隔1秒执行效果可再添加@Async注解,让定时任务支持异步执行;
  • @Scheduled(initialDelay = 1000, fixedRate = 1000):初始化时延迟1秒执行,initialDelay需配置fixedDelayfixedRate

cron规则

表达式

{秒数} {分钟} {小时} {日期} {月份} {星期} {年份(可为空)}

占位符解释

字段允许值允许的特殊字符
秒数0~59- , * /
分钟0~59- , * /
小时0~23- , * /
日期1~31,需注意每个月的天数- , * / ? L W C
月份1~12或JAN-DEC- , * /
星期1~7或SUN-SAT- , * / ? L C #
年份1970~2099,可为空- , * /

星期:1代表星期天(一星期的第一天),7代表星期六(一星期的最后一天)。

特殊字符

  • -代表在指定的范围内触发,比如"25-45"代表从25秒开始触发到45秒结束触发,每隔1秒触发1次
  • ,代表在指定的秒数触发,比如"0,15,45"代表0秒、15秒和45秒时触发任务
  • *代表每隔1秒钟触发
  • /代表触发步进(step),斜杠前面的值代表初始值,后面的值代表偏移量
    • "0/20"或"/20":从0秒钟开始,每隔20秒钟触发1次,即0秒触发1次,20秒触发1次,40秒触发1次
    • "5/20":5秒触发1次,25秒触发1次,45秒触发1次
    • "10-45/20":在[10,45]内步进20秒命中的时间点触发,即10秒触发1次,30秒触发1次
  • ?代表日期星期互斥,即把日期占位符标为问好则代表是指定星期触发,把星期占位符标为问好则代表是指定日期触发
  • L(Last)若用在日期上代表这个月最后一天;若用在星期上代表这周的最后一天即星期六;若用在星期上并且配合数字如"5L"代表这个月的最后一个星期四触发
  • W(Weekday)只用在日期上,代表最接近指定天的工作日(周一到周五),比如"15W":最接近这个月第15天的工作日
    • 如果这个月第15天是周六,那么触发器将会在这个月第14天即周五触发
    • 如果这个月第15天是周日,那么触发器将会在这个月第16天即周一触发
    • 如果这个月第15天是周二,那么就在触发器这天触发
    • 只会在当前月计算值,不会越过当前月
    • "LW"代表这个月的最后一个工作日
  • #只用在星期上,代表这个月的第几个周几,比如"6#3"指这个月第3个周五(6指周五,3指第3个),如果指定的日期不存在,触发器就不会触发
  • C(Calendar)代表依靠一个指定的“日历”,没有“日历”关联,则等价于所有包含的“日历”
    • 用在日期上"5C"表示关联“日历”中第一天,或者这个月开始的第一天的后5天
    • 用在星期上"1C"表示关联“日历”中第一天,或者星期的第一天的后1天,也就是周日的后一天(周一)

举例

  • "0 * 21-23,0-5 * * ?"晚上9点到第二天凌晨5点,每一分钟执行一次(跨天执行)
  • "0 * 17-23/2,8 * * ?"17点到23点每隔两小时和上午8点,每一分钟执行一次
  • "0 0 12 * * ?"每天中午12点触发
  • "0 15 10 ? * *"每天上午10:15触发
  • "0 15 10 * * ?"每天上午10:15触发
  • "0 15 10 * * ? *"每天上午10:15触发
  • "0 15 10 * * ? 2005"2005年的每天上午10:15触发
  • "0 * 14 * * ?"在每天下午2点到下午2:59期间的每1分钟触发
  • "0 0/5 14 * * ?"在每天下午2点到下午2:55期间的每5分钟触发
  • "0 0/5 14,18 * * ?"在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
  • "0 0-5 14 * * ?"在每天下午2点到下午2:05期间的每1分钟触发
  • "0 10,44 14 ? 3 WED"每年三月的星期三的下午2:10和2:44触发
  • "0 15 10 ? * MON-FRI"周一至周五的上午10:15触发
  • "0 15 10 15 * ?"每月15日上午10:15触发
  • "0 15 10 L * ?"每月最后一日的上午10:15触发
  • "0 15 10 ? * 6L"每月的最后一个星期五上午10:15触发
  • "0 15 10 ? * 6L 2002-2005"2002年至2005年的每月的最后一个星期五上午10:15触发
  • "0 15 10 ? * 6#3"每月的第三个星期五上午10:15触发
阅读 670 · 发布于 2019-12-16

————        END        ————

扫描下方二维码关注公众号和小程序↓↓↓

昵称:
随便看看换一批