静态定时任务
cron表达式
cron=“0/25 * * * * ?”
定时任务时间段内执行不完直接跳过下次任务,下例: 25秒,50秒,0秒执行, 注意0秒也执行。
固定间隔
fixedDelay = 1000 * 10
固定间隔执行, 定时任务时间段内执行不完, 下次定时任务在上次执行结束fixedDelay时间后开始执行, 下例: 假如11秒执行,23秒结束,下次33秒开始执行。
固定频率
fixedRate = 1000 * 10
固定频率, 如果任务执行时间超过频率大小, 下次任务直接在上次执行完就开始执行, 下例: 11秒开始,23秒结束, 下次23秒直接开始。
//@Scheduled(cron="0/25 * * * * ?")
//@Scheduled(fixedDelay = 1000 * 10)
@Scheduled(fixedRate = 1000 * 10)
public void test(){
logger.info("开始执行定时任务================");
try {
Thread.sleep(12000);
} catch (InterruptedException e) {
e.printStackTrace();
}
logger.info("定时任务执行完成================");
}
动态定时任务
用途
可以动态改变调度方式等, 相对于静态定时任务, 更加灵活可配置。
实现
实现SchedulingConfigurer接口 org.springframework.scheduling.annotation.SchedulingConfigurer。
同样支持静态任务三种调度方式:
configureTasks()方法中进行配置, 改方法每次任务都会执行;
如果在上述方法中启动了多个定时任务scheduledTaskRegistrar.add多个, 会相互影响, 因为后台其实只起了一个线程, 解决如下: 添加线程池(验证TODO)
scheduledTaskRegistrar.setScheduler(Executors.newScheduledThreadPool(10))
/**
* @desc : 动态定时任务绑定(根据convert.file.method两种配置)
**/
public abstract class ScheduleConfig implements SchedulingConfigurer {
Logger logger = LoggerFactory.getLogger(ScheduleConfig.class);
@Autowired
ConfigBean myConfig;
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
//TODO 设定一个长度为10的定时任务线程池
scheduledTaskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
if ("1".equals(myConfig.getConvertFileMethod())) {
scheduledTaskRegistrar.addTriggerTask(
() -> {
//定时任务具体逻辑
processTask();
},
//定时任务表达式
triggerContext -> {
CronTrigger cronTrigger = new CronTrigger(getCron());
return cronTrigger.nextExecutionTime(triggerContext);
}
);
}else{
scheduledTaskRegistrar.addFixedRateTask(
() -> {
//定时任务具体逻辑
processTask();
},myConfig.getFixRate()
);
}
}
/**
* 任务的处理函数, 本函数需要由派生类根据业务逻辑来实现
*/
abstract void processTask();
/**
* 获取定时任务周期表达式
* 可以将cron表达式存储在数据库中读取使用
*/
private String getCron() {
int mtime = Integer.parseInt(myConfig.getMtime());
String cron = "0/20 * * * * ?";
if("1".equals(myConfig.getCronType())){
if(mtime > 60){
int i = mtime % 60;
cron = "0 */"+ i + " * * * ?";
}else{
cron = "0/" + mtime + " * * * * ?";
}
}
logger.debug("cron表达式为: {}", cron);
return cron;
}
}
注意
静态、动态都需要添加注解 @EnableScheduling 开启定时任务。
总结
Spring Schedule模块相较于 java.util.Timer、Quartz 实现都比较简单, 而且能够满足大多数需求; 简单、快速、高效、稳定的定时任务调度框架。
参考
https://blog.csdn.net/u013998466/article/details/90373811