SpringBoot实现定时任务的动态停止和更新

发布于:2024-06-26 ⋅ 阅读:(60) ⋅ 点赞:(0)

定时任务管理器

  • 负责启动一个定时任务、停止一个定时任务、更新一个定时任务
/**
 * 定时任务管理器
 * 1、创建并启动一个定时任务
 * 2、停止一个定时任务
 * 3、更新一个定时任务
 */
public class ScheduleManager {

    private final Logger logger = LoggerFactory.getLogger(ScheduleManager.class);

    @Autowired
    private ThreadPoolTaskScheduler taskScheduler;

    /**
     * 内部正在执行的定时任务缓存
     */
    private final Map<String, ScheduleTaskHolder> cache = new ConcurrentHashMap<>();

    public ScheduleManager(ThreadPoolTaskScheduler taskScheduler) {
        this.taskScheduler = taskScheduler;
    }

    /**
     * 启动一个定时任务
     *
     * @param scheduleTask 定时任务实现类
     * @param cron         定时任务的cron表达式
     * @return key
     */
    public String startTask(ScheduleTask scheduleTask, String cron) {
        ScheduledFuture<?> scheduledFuture = taskScheduler.schedule(scheduleTask, new CronTrigger(cron));
        String key = UUID.randomUUID().toString();
        ScheduleTaskHolder holder = new ScheduleTaskHolder(scheduleTask, scheduledFuture);
        cache.put(key, holder);
        logger.info("{} 定时任务启动成功!唯一标识为:{}", scheduleTask.getName(), key);
        return key;
    }

    /**
     * 停止一个定时任务
     *
     * @param key 定时任务的唯一标识
     */
    public void stopTask(String key) {
        if (StringUtils.isBlank(key)) {
            return;
        }
        ScheduleTaskHolder holder = cache.get(key);
        if (Objects.isNull(holder)) {
            return;
        }
        ScheduledFuture scheduledFuture = holder.getScheduledFuture();
        boolean cancel = scheduledFuture.cancel(true);
        if (cancel) {
            logger.info("{} 定时任务停止成功!唯一标识为:{}", holder.getScheduleTask().getName(), key);
        } else {
            logger.error("{} 定时任务停止失败!唯一标识为:{}", holder.getScheduleTask().getName(), key);
        }
    }

    /**
     * 更新一个定时任务的执行时间
     *
     * @param key  定时任务的唯一标识
     * @param cron 新的cron表达式
     * @return key
     */
    public String changeTask(String key, String cron) {
        if (StringUtils.isAnyBlank(key, cron)) {
            throw new RuntimeException("定时任务的唯一标识以及新的执行表达式不能为空");
        }
        ScheduleTaskHolder holder = cache.get(key);
        if (Objects.isNull(holder)) {
            throw new RuntimeException(key + "唯一标识不存在");
        }
        stopTask(key);
        return startTask(holder.getScheduleTask(), cron);
    }

}

定时任务的任务接口

  • 定时任务的运行逻辑在重写的 run 方法中实现
/**
 * 定时任务的任务接口
 */
public interface ScheduleTask extends Runnable {

    /**
     * 获取定时任务的名称
     *
     * @return
     */
    String getName();

}

定时任务和定时任务结果的缓存对象

  • 负责缓存定时任务和控制该定时任务
/**
 * 定时任务和定时任务结果的缓存对象
 */
public class ScheduleTaskHolder implements Serializable {

    /**
     * 执行任务实体
     */
    private ScheduleTask scheduleTask;

    /**
     * 执行任务的结果实体
     */
    private ScheduledFuture scheduledFuture;

    public ScheduleTaskHolder() {
    }

    public ScheduleTaskHolder(ScheduleTask scheduleTask, ScheduledFuture scheduledFuture) {
        this.scheduleTask = scheduleTask;
        this.scheduledFuture = scheduledFuture;
    }

    public ScheduleTask getScheduleTask() {
        return scheduleTask;
    }

    public void setScheduleTask(ScheduleTask scheduleTask) {
        this.scheduleTask = scheduleTask;
    }

    public ScheduledFuture getScheduledFuture() {
        return scheduledFuture;
    }

    public void setScheduledFuture(ScheduledFuture scheduledFuture) {
        this.scheduledFuture = scheduledFuture;
    }
}

定时任务

  • 具体实现的定时任务
/**
 * 定时任务
 */
public class ThreadPoolWarnTask implements ScheduleTask {

    @Override
    public String getName() {
        return "threadPoolWarnTask";
    }

    @Override
    public void run() {

    }
}

使用姿势

  • 引入 ScheduleManager 对象
  • 开启定时任务、关闭定时任务、更新定时任务
// 传入一个定时任务和CRON表达式开启定时任务,返回该定时任务的唯一标识
String taskKey = scheduleManager.startTask(threadPoolWarnTask, CRON);
// 停止定时任务
scheduleManager.stopTask(taskKey);
// 更新定时任务的CRON
scheduleManager.changeTask(taskKey, newCRON);

网站公告

今日签到

点亮在社区的每一天
去签到