SpringBoot自带的 Schedule,可以将它看成一个轻量级的Quartz,而且使用起来比Quartz简单许多
以下任务都是在单线程下执行的
有两种方法设置执行时机
1.fixedRate:会为所有任务的开始执行时间编排一个表,假如fixedRate=5000,且第一次开始时间是10:00:00
当执行任务耗时小于fixedRate设置的时间时,将会按照表中的开始时间执行任务,即每隔5秒会执行一个任务:
@Slf4j
@Component
public class ScheduleTaskServer {
@Autowired
private TopicNewsMapper topicNewsMapper;
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Scheduled(fixedRate=5000)
public void scheduleUpdateNewsCount(){
log.info("执行时间:{}",sdf.format(new Date()));
}
}
当执行任务耗时大于fixedRate设置的时间时,以下一张图就很清楚的表示了
解析一下:
fixedRate设置的也是为fixedRate=5000
第一个任务开始执行时间是0:00,耗时8秒
第二个任务本应该开始执行时间是0:05,但是第一个任务执行完时间已经是0:08,所以第二个任务在第一个任务执行完毕之后会立即执行,耗时是3s
第三个任务本应该开始执行时间是0:10,但是前两个任务执行完毕时间已经是0:11,所以第三个任务在第二个任务执行完毕之后会立即执行,耗时是6s
第四个任务,也同第二、第三个任务一样,在预计开始执行的时间(这里第四个任务预计开始执行时间是0:15),因为上一个任务还没有执行完毕,所以要等待上一个人执行完毕之后才会执行。
第五个任务预计开始执行时间是0:20,而前四个任务在0:19已经执行完毕,需要等待1秒,到达我们预计的开始执行时间(0:20)才会执行第五个任务。
2.fixedDelay
这个就比之前的fixedRate简单得多。如设置fixedRate=5000.下一个任务只需要盯着上一个任务的屁股(执行完毕的时间)就行了。上一个任务执行完毕5秒之后,下一个任务就会开始执行
@Scheduled(fixedDelay=5000)
public void myTask(){
log.info("开始执行时间:{}",sdf.format(new Date()));
try {
//让任务执行的耗时时间为8秒,有利于我们的观察
Thread.sleep(8000);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("执行完毕时间:{}",sdf.format(new Date()));
}
3.initialDelay
用于配合fixedRate和fixedDelay使用的,作用是在容器启动后经过多长时间才开始执行第一次任务。
4.扩展一下
我们先看下一下@Scheduled注解里面有什么
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {
String CRON_DISABLED = "-";
String cron() default "";
String zone() default "";
long fixedDelay() default -1L;
String fixedDelayString() default "";
long fixedRate() default -1L;
String fixedRateString() default "";
long initialDelay() default -1L;
String initialDelayString() default "";
}
fixedDelayString、fixedRateString和initialDelayString不就是我们上面讲的三个加个字符串嘛,之前的三个都是long类型,这三个是String类型,顾名思义,不就是用字符串表示嘛。作用其实就是为了能在application.properties配置
@Scheduled(fixedDelay=5000, fixedDelayString = "${com.liang.scheduled:5000}")
public void myTask(){
log.info("开始执行时间:{}",sdf.format(new Date()));
try {
//让任务执行的耗时时间为8秒,有利于我们的观察
Thread.sleep(8000);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("执行完毕时间:{}",sdf.format(new Date()));
}
:5000作用是防止application.properties没有配置com.liang.scheduled属性则使用默认的5000(如果没有写:5000且application.properties没有配置com.liang.scheduled属性会报异常)
执行结果:和我们预计的一样,下一次开始执行时间与上一次结束时间间隔正好是10秒。如果去掉application.properties中的com.liang.scheduled属性,则间隔时间是默认的5秒,这个自行验证。
网站:
这个自行去网站上设置,然后复制表达式过来就行,
@Slf4j
@Component
public class ScheduleTaskServer {
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 每20秒执行一次
@Scheduled(cron = "0/20 * * * * ?")
public void scheduleUpdateNewsCount(){
log.info("执行时间:{}",sdf.format(new Date()));
}
}
欢迎留言。。。