Spring 4和SpringBoot 1.5中常见的使用定时调度方式
@Scheduled(cron = "1 * * * * ?")
public void check() {
try {
System.out.printf("Time: %s, thread: %s.%n",
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now()),
Thread.currentThread().getName());
TimeUnit.SECONDS.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
最近项目中需要让用户在前端配置定时触发任务,由于触发的任务数量并不多,且应用不是分布式程序,所以考虑就不考虑使用quartz,简单使用Spring的Schedule来实现。
通过ScheduleConfig启用Schedule并配置执行任务的执行器(实现TaskScheduler/ScheduledExecutorService对象,如果都没有则创建一个只有一个线程的线程池[org.springframework.scheduling.config.ScheduledTaskRegistrar#scheduleTasks])以及对外暴露ScheduledTaskRegistrar。
@SpringBootConfiguration
@EnableScheduling
public class ScheduleConfig implements SchedulingConfigurer {
private ScheduledTaskRegistrar taskRegistrar;
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
this.taskRegistrar = taskRegistrar;
taskRegistrar.setScheduler(taskExecutor());
}
@Bean(destroyMethod = "shutdown")
public ThreadPoolExecutor taskExecutor() {
return (ThreadPoolExecutor) Executors.newScheduledThreadPool(20);
}
public ScheduledTaskRegistrar getTaskRegistrar() {
return taskRegistrar;
}
}
在service中通过ScheduleConfig获取到ScheduledTaskRegistrar,通过ScheduledTaskRegistrar的scheduleCronTask方法可以添加新任务,返回值是一个ScheduledTask对象,通过该对象的cancel方法可以取消该任务的执行,再拿一个map保存任务的id和ScheduledTask对象即可,demo如下:
@Service
public class TaskService {
private final ScheduleConfig scheduleConfig;
// 保存已经配置的定时任务
private final Map<Integer, ScheduledTask> scheduledTasks = new HashMap<>();
public TaskService(ScheduleConfig scheduleConfig) {
this.scheduleConfig = scheduleConfig;
}
private ScheduledTaskRegistrar getRegistrar() {
return scheduleConfig.getTaskRegistrar();
}
/**
* 处理前端封装的参数
*/
public synchronized void processTask(XmonAlertTaskWrapper wrapper) {
int id = wrapper.getId();
if ("add".equals(wrapper.getAction())) {
CronTask cronTask = new CronTask(new XmonAlert(wrapper.getMsg()), wrapper.getExpression());
if (scheduledTasks.containsKey(id)) {
// map中存在表示需要修改该任务,先取消之前的任务
scheduledTasks.get(id).cancel();
}
// 添加新的任务
ScheduledTask scheduledTask = getRegistrar().scheduleCronTask(cronTask);
scheduledTasks.put(id, scheduledTask);
System.out.println("添加" + wrapper + "成功.");
} else {
// 删除任务
if (scheduledTasks.containsKey(id)) {
// 取消任务的执行
scheduledTasks.get(id).cancel();
// map中删除该任务
scheduledTasks.remove(id);
}
System.out.println("删除" + wrapper + "成功.");
}
}
/**
* 定时执行的任务
*/
static class XmonAlert implements Runnable {
private final String msg;
public XmonAlert(String msg) {
this.msg = msg;
}
@Override
public void run() {
try {
System.out.printf("Time: %s, thread: %s, msg: %s.%n",
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now()), Thread.currentThread().getName(), msg);
TimeUnit.SECONDS.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}