最近的工作业务中,涉及到了一个动态的定时任务功能,用户在页面中生成cron表达式,后台进行一个动态定时任务的启停功能
用到了以下几个与定时任务相关的工具类及接口
ScheduledTaskRegistrar
ScheduledFuture
SchedulingConfigurer
CronTask
1.实现SchedulingConfigurer接口,在重写的方法中为ScheduledTaskRegistrar创建一个定时任务的线程池,数量根据业务的情况来决定,这里只做演示
2.接着实现任务的动态绑定与启停,这里只做简单实现的演示
3.实体类
具体代码如下
@Component
public class CronTest implements SchedulingConfigurer {
private volatile ScheduledTaskRegistrar registrar;
private final ConcurrentHashMap<String,ScheduledFuture> map = new ConcurrentHashMap<>();
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
scheduledTaskRegistrar.setScheduler(Executors.newScheduledThreadPool(3));
this.registrar = scheduledTaskRegistrar;
}
public void invalidTask(List<TaskTest> taskList){
if(map.size() != 0){
map.keySet().forEach(key -> {
map.get(key).cancel(false);
});
}
if(taskList.size() != 0){
taskList.forEach(item->{
String cron = item.getCron();
CronTask cronTask = new CronTask(new Runnable() {
@Override
public void run() {
System.out.println("线程:"+Thread.currentThread().getName()+"执行了id: "+item.getId()+"的任务!");
}
},cron);
ScheduledFuture<?> schedule = registrar.getScheduler().schedule(cronTask.getRunnable(), cronTask.getTrigger());
map.put(item.getId(),schedule);
});
}
}
}
controller层(用postman做测试)
@Autowired
private CronTest cronTest;
@PostMapping("/cron1")
public void testCron(@RequestBody JSONObject jsonObject){
JSONArray testCron = jsonObject.getJSONArray("testCron");
List<TaskTest> list = new ArrayList<>();
for (int i = 0; i < testCron.size(); i++) {
JSONObject json = testCron.getJSONObject(i);
TaskTest test = new TaskTest();
test.setId(json.getString("id"));
test.setName(json.getString("name"));
test.setCron(json.getString("cron"));
list.add(test);
}
cronTest.invalidTask(list);
}
postman请求的JSON数据
{
"testCron":[
{
"id":"1",
"name":"第一",
"cron":"0/10 * * * * ?"
},
{
"id":"2",
"name":"第二",
"cron":"0/20 * * * * ?"
},
{
"id":"3",
"name":"第三",
"cron":"0/30 * * * * ?"
}
]
}
欢迎交流。。。