本文测试了@scheduled注解中参数cron,fixedDelay,fixedRate参数周期性调度任务时,任务执行时长不同对任务调度的影响情况,包含作业任务执行时长小于任务执行周期,作业任务执行时长与任务执行频率同频,作业任务执行时长大于任务执行周期的三种情况,用于对实际业务设置定时执行作为参考。
模拟定时周期为3秒执行一次,任务执行耗时1秒,执行结果如图所示:第一次作业开始时间为16:25:36,结束时间为16:25:37,第二次作业开始时间为:16:25:39,结束时间为16:25:40,第三次作业开始时间为16:25:43。由执行结果可知:作业调度依次间隔为3秒钟时间执行一次,符合预期。
/**
* 任务周期3S 模拟作业执行时长 1S
*/
@Scheduled(cron = "0/3 * * * * ?")
public void testJobCron() throws InterruptedException {
log.info("->TID:{}任务开始{}",Thread.currentThread().getId(), DateUtil.currentLongDateTime());
Thread.sleep(1000);
log.info("<-TID:{}任务结束{}",Thread.currentThread().getId(), DateUtil.currentLongDateTime());
}
模拟定时周期为3秒执行一次,任务执行耗时3秒,执行结果如图所示:第一次作业开始时间为16:31:48,结束时间为16:31:51,第二次作业开始时间为:16:31:54,结束时间为16:31:57,第三次作业开始时间为16:32:00。由执行结果可知:作业调度间隔已经不是3秒钟时间执行一次(作业完后3秒执行下一次调度),不符合预期。
/**
* 任务周期3S 模拟作业执行时长 3S
*/
@Scheduled(cron = "0/3 * * * * ?")
public void testJobCron() throws InterruptedException {
log.info("->TID:{}任务开始{}",Thread.currentThread().getId(), DateUtil.currentLongDateTime());
Thread.sleep(3000);
log.info("<-TID:{}任务结束{}",Thread.currentThread().getId(), DateUtil.currentLongDateTime());
}
模拟定时周期为3秒执行一次,任务执行耗时5秒,执行结果如图所示:第一次作业开始时间为16:33:24,结束时间为16:33:29,第二次作业开始时间为:16:33:30,结束时间为16:33:35,第三次作业开始时间为16:33:36。由执行结果可知:任务调度间隔不为3秒钟时间执行一次(作业完后隔1秒钟执行下一次调度),不符合预期。
/**
* 任务周期3S 模拟作业执行时长 5S
*/
@Scheduled(cron = "0/3 * * * * ?")
public void testJobCron() throws InterruptedException {
log.info("->TID:{}任务开始{}",Thread.currentThread().getId(), DateUtil.currentLongDateTime());
Thread.sleep(5000);
log.info("<-TID:{}任务结束{}",Thread.currentThread().getId(), DateUtil.currentLongDateTime());
}
模拟定时周期为3秒执行一次,任务执行耗时1秒,执行结果如图所示:第一次作业开始时间为16:35:45,结束时间为16:35:46,第二次作业开始时间为:16:35:48,结束时间为16:35:49,第三次作业开始时间为16:35:51。由执行结果可知:作业调度依次间隔为3秒钟时间执行一次,符合预期。
/**
* 3S执行一次 模拟作业执行时长1S
* 上一次开始执行时间点之后多长时间再执行
*/
@Scheduled(fixedRate = 3000L)
public void testJobFixedRate() throws InterruptedException {
log.info("->TID:{}任务开始{}",Thread.currentThread().getId(), DateUtil.currentLongDateTime());
Thread.sleep(1000);
log.info("<-TID:{}任务结束{}",Thread.currentThread().getId(), DateUtil.currentLongDateTime());
}
模拟定时周期为3秒执行一次,任务执行耗时3秒,执行结果如图所示:第一次作业开始时间为16:37:20,结束时间为16:37:23,第二次作业开始时间为:16:37:23,结束时间为16:37:26,第三次作业开始时间为16:37:26。由执行结果可知:作业调度间隔3秒钟时间执行一次(作业完后立即执行下一次调度),符合预期。
/**
* 3S执行一次 模拟作业执行时长3S
* 上一次开始执行时间点之后多长时间再执行
*/
@Scheduled(fixedRate = 3000L)
public void testJobFixedRate() throws InterruptedException {
log.info("->TID:{}任务开始{}",Thread.currentThread().getId(), DateUtil.currentLongDateTime());
Thread.sleep(3000);
log.info("<-TID:{}任务结束{}",Thread.currentThread().getId(), DateUtil.currentLongDateTime());
}
模拟定时周期为3秒执行一次,任务执行耗时5秒,执行结果如图所示:第一次作业开始时间为16:39:52,结束时间为16:39:57,第二次作业开始时间为:16:39:57,结束时间为16:40:02,第三次作业开始时间为16:40:02。由执行结果可知:任务调度间隔不为3秒钟时间执行一次(作业完后立即执行下一次调度,调度间隔由任务执行时长决定),不符合预期。
/**
* 3S执行一次 模拟作业执行时长5S
* 上一次开始执行时间点之后多长时间再执行
*/
@Scheduled(fixedRate = 3000L)
public void testJobFixedRate() throws InterruptedException {
log.info("->TID:{}任务开始{}",Thread.currentThread().getId(), DateUtil.currentLongDateTime());
Thread.sleep(5000);
log.info("<-TID:{}任务结束{}",Thread.currentThread().getId(), DateUtil.currentLongDateTime());
}
模拟定时周期为3秒执行一次,任务执行耗时1秒,执行结果如图所示:第一次作业开始时间为16:42:32,结束时间为16:42:33,第二次作业开始时间为:16:42:36,结束时间为16:42:37,第三次作业开始时间为16:42:40。由执行结果可知:作业调度依次为执行结束后间隔3秒钟时间执行下一次任务,符合预期。
/**
* 3S执行一次 模拟作业执行时长1S
* 上一次执行完毕时间点之后多长时间再执行
*/
@Scheduled(fixedDelay = 3000L)
public void testJobFixedDelay() throws InterruptedException {
log.info("->TID:{}任务开始{}",Thread.currentThread().getId(), DateUtil.currentLongDateTime());
Thread.sleep(1000);
log.info("<-TID:{}任务结束{}",Thread.currentThread().getId(), DateUtil.currentLongDateTime());
}
模拟定时周期为3秒执行一次,任务执行耗时3秒,执行结果如图所示:第一次作业开始时间为16:44:11,结束时间为16:44:14,第二次作业开始时间为:16:44:17,结束时间为16:44:20,第三次作业开始时间为16:44:23。由执行结果可知:作业调度依次为执行结束后间隔3秒钟时间执行下一次任务,符合预期。
/**
* 3S执行一次 模拟作业执行时长3S
* 上一次执行完毕时间点之后多长时间再执行
*/
@Scheduled(fixedDelay = 3000L)
public void testJobFixedDelay() throws InterruptedException {
log.info("->TID:{}任务开始{}",Thread.currentThread().getId(), DateUtil.currentLongDateTime());
Thread.sleep(3000);
log.info("<-TID:{}任务结束{}",Thread.currentThread().getId(), DateUtil.currentLongDateTime());
}
模拟定时周期为3秒执行一次,任务执行耗时5秒,执行结果如图所示:第一次作业开始时间为16:45:57,结束时间为16:46:02,第二次作业开始时间为:16:46:05,结束时间为16:46:10,第三次作业开始时间为16:46:13。由执行结果可知:作业调度依次为执行结束后间隔3秒钟时间执行下一次任务,符合预期。
/**
* 3S执行一次 模拟作业执行时长5S
* 上一次执行完毕时间点之后多长时间再执行
*/
@Scheduled(fixedDelay = 3000L)
public void testJobFixedDelay() throws InterruptedException {
log.info("->TID:{}任务开始{}",Thread.currentThread().getId(), DateUtil.currentLongDateTime());
Thread.sleep(5000);
log.info("<-TID:{}任务结束{}",Thread.currentThread().getId(), DateUtil.currentLongDateTime());
}
支持cron表达式方式进行作业调度。
将解析 cron 表达式的时区。默认情况下,此属性是空字符串(即将使用服务器的本地时区)。
上一次执行完毕时间点之后多长时间再执行。
意思fixedDelay相同,只是使用字符串的形式。支持配置文件中配置参数,采用占位符获取配置参数的情形。
上一次开始执行时间点之后多长时间再执行。
意思fixedRate相同,只是使用字符串的形式。支持配置文件中配置参数,采用占位符获取配置参数的情形。
配合fixedDelay与fixedRate一起使用,在第一次执行任务之前延迟的毫秒数。
意思initialDelay相同,只是使用字符串的形式。支持配置文件中配置参数,采用占位符获取配置参数的情形
测试类不包含包名,可自行导入,有兴趣的同学还可以观察一下线程ID,可以测试一下多个调度任务线程执行情况。
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@EnableScheduling
public class TestHandleJob {
/**
* 任务周期3S 模拟作业执行时长 1S
*/
@Scheduled(cron = "0/3 * * * * ?")
public void testJobCron() throws InterruptedException {
log.info("->TID:{}任务开始{}",Thread.currentThread().getId(), DateUtil.currentLongDateTime());
Thread.sleep(1000);
log.info("<-TID:{}任务结束{}",Thread.currentThread().getId(), DateUtil.currentLongDateTime());
}
/**
* 3S执行一次 模拟作业执行时长5S
* 上一次开始执行时间点之后多长时间再执行
*/
//@Scheduled(fixedRate = 3000L)
public void testJobFixedRate() throws InterruptedException {
log.info("->TID:{}任务开始{}",Thread.currentThread().getId(), DateUtil.currentLongDateTime());
Thread.sleep(5000);
log.info("<-TID:{}任务结束{}",Thread.currentThread().getId(), DateUtil.currentLongDateTime());
}
/**
* 3S执行一次 模拟作业执行时长5S
* 上一次执行完毕时间点之后多长时间再执行
*/
//@Scheduled(fixedDelay = 3000L)
public void testJobFixedDelay() throws InterruptedException {
log.info("->TID:{}任务开始{}",Thread.currentThread().getId(), DateUtil.currentLongDateTime());
Thread.sleep(5000);
log.info("<-TID:{}任务结束{}",Thread.currentThread().getId(), DateUtil.currentLongDateTime());
}
}