Spring Task定时任务

SpringTask 默认是单线程的 上面的两个定时任务使用的都是同一个线程;在实际开发中,不希望所有的任务都运行在一个线程中,想要改成多线程,给SpringTask提供一个多线程的TaskScheduler

Spring Task定时任务:spring通过接口TaskExecutorTaskScheduler这两个接口的方式为异步定时任务提供了一种抽象。spring自身也提供了一种定时任务的实现:spring task。spring task支持线程池,可以高效处理许多不同的定时任务。同时,spring还支持使用Java自带的Timer定时器和Quartz定时框架。

TaskExecutor是spring task的第一个抽象,这里补充一个jdk中concurrent包下的Executor,实际上TaskExecutor就是为区别于Executor才引入的,而引入TaskExecutor的目的:为定时任务的执行提供线程池的支持 ,TaskExecutor提供的线程池支持也是基于jdk自带的Executor的

TaskScheduler是spring task的第二个抽象,TaskScheduler就是为了提供定时任务的支持咯。TaskScheduler需要传入一个Runnable的任务做为参数,并指定需要周期执行的时间或者触发器,这样Runnable任务就可以周期性执行了。传入时间很好理解,有意思的是传入一个触发器(Trigger)的情况,因为这里需要使用cron表达式去触发一个定时任务,所以有必要先了解下cron表达式的使用。

cron表达式的格式如下

{秒} {分} {时} {日期(具体哪天)} {月} {星期}

:必填项,允许的值范围是0-59,支持的特殊符号包括
, - /,,表示特定的某一秒才会触发任务,-表示一段时间内会触发任务,表示每一秒都会触发,/表示从哪一个时刻开始,每隔多长时间触发一次任务。
:必填项,允许的值范围是0-59,支持的特殊符号和秒一样,含义类推
:必填项,允许的值范围是0-23,支持的特殊符号和秒一样,含义类推
日期:必填项,允许的值范围是1-31,支持的特殊符号相比秒多了?,表示与{星期}互斥,即意味着若明确指定{星期}触发,则表示{日期}无意义,以免引起冲突和混乱。
:必填项,允许的值范围是1-12(JAN-DEC),支持的特殊符号与秒一样,含义类推
星期:必填项,允许值范围是1~7 (SUN-SAT),1代表星期天(一星期的第一天),以此类推,7代表星期六,支持的符号相比秒多了?,表达的含义是与{日期}互斥,即意味着若明确指定{日期}触发,则表示{星期}无意义。

spring提供了一个CronTrigger,通过传入一个Runnable任务和CronTrigger,就可以使用cron表达式去指定定时任务

TaskScheduler抽象的好处是让需要执行定时任务的代码不需要指定特定的定时框架(比如Timer和Quartz)。TaskScheduler的更简单的实现是ThreadPoolTaskScheduler,它实际上代理一个jdk中的SchedulingTaskExecutor,并且也实现了TaskExecutor接口,所以需要经常执行定时任务的场景可以使用这个实现。

实现方式:注解和xml配置文件

创建Maven工程,pom.xml

<groupId>com.rhwayfun</groupId>
<artifactId>sring-task-demo</artifactId>
<version>1.0-SNAPSHOT</version>

开发需要执行定时任务的方法:

@Component
public class App {

  1. public void execute1(){
  2. System.out.printf("Task: %s, Current time: %s\n", 1, LocalDateTime.now());
  3. }