我们在Java中可以通过Timer类来执行定时任务,在spring中,给我提供了更加便捷的计划任务。我们可以通过@EnableScheduling来开启计划任务,通过@Scheduled来定义一个计划任务。
我们先来看@Scheduled的源码
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {
String cron() default "";
String zone() default "";
long fixedDelay() default -1;
String fixedDelayString() default "";
long fixedRate() default -1;
String fixedRateString() default "";
long initialDelay() default -1;
String initialDelayString() default "";
}
我们可以通过 cron,fixDelay,fixRate来定义多种计划任务。
cron 是通过指定cron表达式来指定任务的执行时间,是Linux下的定时任务
fixDelay 是通过指定完成上一个任务后的延时时间来执行下一个任务
fixRate 是通过指定固定间隔时间来执行计划任务
下面来举例说明,首先是计划任务的执行类
package com.hy.spring.test8;
import java.util.Random;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@Service
public class ScheduledTaskService {
// 每隔5s执行一次
@Scheduled(fixedRate=5000)
public void test1() {
System.out.println("test1 is running ... ");
}
// 指定时间执行,同linux下的定时任务
// 秒(0~59)
// 分钟(0~59)
// 小时(0~23)
// 天(月)(0~31,但是你需要考虑你月的天数)
// 月(0~11)
// 天(星期)(1~7 1=SUN 或 SUN,MON,TUE,WED,THU,FRI,SAT)
// 年份(1970-2099)
// * 表示所有可能的值
// ? 表示天的不确定值
@Scheduled(cron="0 * 17 ? * *") // 这里指定的是 在每天的17:任何一分种的第0秒来执行
public void test2() {
System.out.println("test2 is running...");
}
// 在上一个任务完成之后5s执行
@Scheduled(fixedDelay=5000)
public void test3() {
System.out.println("test3 is running ...");
try {
Thread.sleep(new Random().nextInt(3000)); // 这里模拟任务的延时
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
这里再来解释一下关于fixedDelay和fixedRate,都是间隔一定的时间执行,fixedRete是每隔5s就执行一次。fixedDelay是当上一次的任务执行完毕开始计时,5s后再来执行下一次的任务。通过结果我们可以看到,test3执行的频率一定是低于test1的,即便在test1中也使用休眠。
配置类
package com.hy.spring.test8;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
@Configuration
@ComponentScan("com.hy.spring.test8")
@EnableScheduling // 启用计划任务
public class TaskSchedulerConfig {
}
测试类
package com.hy.spring.test8;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TaskSchedulerConfig.class);
}
}
执行结果
test1 is running ... pool-1-thread-1
test3 is running ...pool-1-thread-1
test1 is running ... pool-1-thread-1
test1 is running ... pool-1-thread-1
test3 is running ...pool-1-thread-1
test1 is running ... pool-1-thread-1
test3 is running ...pool-1-thread-1
test1 is running ... pool-1-thread-1
test3 is running ...pool-1-thread-1
test1 is running ... pool-1-thread-1
test2 is running...pool-1-thread-1
test1 is running ... pool-1-thread-1
test3 is running ...pool-1-thread-1