1 概述

定时任务,特定的时间执行任务,在项目中普遍使用。本文介绍简单的无状态无持久化的定时任务实现方式;Timer,ScheduledExecutorService,Spring Task。

2 Timer实现方式

JDK自带的java.util.Timer;通过调度java.util.TimerTask的方式 让程序按照某一个频度执行,但不能在指定时间运行。一般用的较少。

3 ScheduledExecutorService实现方式

ScheduledExecutorService,JDK1.5新增的,位于java.util.concurrent包中;是基于线程池设计的定时任务类,每个调度任务都会被分配到线程池中,并发执行,互不影响。

与Timer很类似,但它的效果更好;多线程并行处理定时任务时,Timer运行多个TimeTask时,只要其中有一个因任务报错没有捕获抛出的异常,其它任务便会自动终止运行,使用 ScheduledExecutorService则可以规避这个问题。

4 Spring Task`实现方式(推荐)

Spring Task, Spring3.0 以后新增了task,一个轻量级的Quartz,功能够用,用法简单。

Spring Task在spring-context的org.springframework.scheduling下,只需要依赖spring-boot-starter-web即可。

@Scheduled注解, Spring Task定时任务的核心

cron:cron表达式,根据表达式循环执行,与fixedRate属性不同的是它是将时间进行了切割。@Scheduled(cron = "0/5 * * * * *"任务将在5、10、15、20…这种情况下执行。fixedRate: 每隔多久执行一次;@Scheduled(fixedRate = 1000假设第一次工作时间为2018-09-28 10:58:28,工作时长为3秒,那么下次任务的时候就是2018-09-28 10:58:31;配置成异步后,只要到了执行时间就会开辟新的线程工作,如果@Scheduled(fixedRate = 1000假设第一次工作时间为2018-09-28 10:58:28,工作时长为3秒,那么下次任务的时间是2018-09-28 10:58:29。fixedDelay: 当前任务执行完毕后等待多久继续下次任务@Scheduled(fixedDelay = 3000假设第一次任务工作时间为2018-09-28 10:58:30,工作时长为5秒,那么下次任务的时间就是2018-09-28 10:58:38。initialDelay: 第一次执行延迟时间,只是做延迟的设定,与fixedDelay关系密切,配合使用,相辅相成。

@Async注解,代表该任务可以进行异步工作,由串行改为并行。

cron表达式在线生成: http://www.pdtools.net/tools/becron.jsp

开启任务

@EnableScheduling注解表示开启对@Scheduled注解的解析;同时new ThreadPoolTaskScheduler()也是相当的关键,通过阅读过源码可以发现默认情况下的 private volatile int poolSize = 1;这就导致了多个任务的情况下容易出现竞争情况,多个任务的情况下,如果第一个任务没执行完毕,后续的任务将会进入等待状态。@EnableAsync注解表示开启@Async注解的解析;作用就是将串行化的任务给并行化。

5 测试结果

请自己动动手

6 工程目录

7 结束语

后续文章会陆续介绍,Quartz,以及基于Quartz实现的分布式任务项目,xxl-job,elastic-job,尽情期待,附本文源码链接:https://github.com/Mkeeper6/SpringBoot-About

查看原文 >>
相关文章