Spring Boot实现简单的定时任务:https://blog.csdn.net/duan196_118/article/details/107654743。在这个案例中,我们可以实现简单的定时任务,本篇博客介绍的是动态的执行定时任务,即动态修改定时任务的执行间隔。案例在单体环境下可以实现需求,但还存在这问题,希望看到的小伙伴可以提出您宝贵的意见,望不吝赐教。
场景:
在与硬件对接的项目中,每隔一段时间要存储硬件发送的数据,而这个时间间隔需要动态的改变。
思路:
首先想到的是@Scheduled(cron =“0/5 * * * * *”)这种方式适用于固定任务周期的任务,若要修改任务执行周期,只能走“停服务—修改任务执行周期—重启服务”这条路。
如何动态修改呢?
1. 在定时任务类上增加@EnableScheduling注解,并实现SchedulingConfigurer接口
2.设置一个静态的cron,用于存放任务执行周期参数。
3.开启一个线程,用于实际业务中外部原因修改了任务执行周期。
4.设置任务触发器,触发任务执行。
具体代码如下:
package com.py.monitorPoint.web.controller;
import com.py.monitorPoint.mapper.DataMapper;
import com.py.monitorPoint.web.service.DataService;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Date;
/**
* Spring @Scheduled定时任务动态修改cron参数
* @author Angel --曰业而安
* @version v.0.1
* @date 2020年8月29日
*/
@Component
@EnableScheduling
public class TaskCronChange implements SchedulingConfigurer {
@Resource
private DataMapper dataMapper;
@Resource
private MonitorService mpc;
public String NewCrons(){
String numStr = dataMapper.getNum().trim();
return numStr;
}
public static String cron;
public TaskCronChange() {
//默认情况是:每1分执行一次.
cron = "0 */1 * * * ?";
new Thread(new Runnable() {
// 开启新线程模拟外部更改了任务执行周期.
@Override
public void run() {
try {
// 让线程睡眠 15秒.
Thread.sleep(15000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//修改为:设定的周期.
cron = "0 0 */"+NewCrons()+" * * ?";
System.err.println("cron change to:"+cron);
}
}).start();;
}
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
Runnable task = new Runnable() {
@Override
public void run() {
//任务逻辑代码部分.
System.out.println("TaskCronChange task is running ... "+ new Date());
mpc.timerNum();//执行任务逻辑
}
};
Trigger trigger = new Trigger() {
@Override
public Date nextExecutionTime(TriggerContext triggerContext) {
//任务触发,可修改任务的执行周期.
CronTrigger trigger = new CronTrigger(cron);
Date nextExec = trigger.nextExecutionTime(triggerContext);
return nextExec;
}
};
taskRegistrar.addTriggerTask(task, trigger);
}
}
需求得以实现,但是在并发环境下还有需要优化的地方。望不吝赐教,您的宝贵意见将促使码农的成长!