基于Spring的动态定时任务,可动态开启、关闭和取消任务

  • Post author:
  • Post category:其他




无配置文件实现动态定时任务,超级简单


定时任务抽象类

ScheduleTask ,为具体的任务类提供了模板方法

/**
 * 定时任务抽象类(父类)
 * 具体执行方法请继承该类,然后重写run方法
 */
public abstract class ScheduleTask implements Runnable {
    private String id;

    public void setId(String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }

    public ScheduleTask(String id) {
        this.id = id;
    }

    @Override
    public abstract void run();
}


工具类

ScheduleUtil 。用于实现任务的开启、关闭、时间设置等操作

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;

/**
 * 定时任务工具类
 *
 */
public class ScheduleUtil {
    private static final Log logger = LogFactory.getLog(ScheduleUtil.class);

    private static ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
    private static Map<String, ScheduledFuture<?>> scheduledFutureMap = new HashMap<>();
    static{
        threadPoolTaskScheduler.initialize();
        logger.info("初始化线程池...");
    }
    /**
     * 启动某定时任务,到时间点就运行一次
     * @param scheduleTask
     * @param startTime
     */
    public static void start(ScheduleTask scheduleTask, Date startTime){
        if (isExist(scheduleTask.getId())){
            logger.info("启动定时任务"+ scheduleTask.getId()+"失败,任务已存在");
            return;
        }
        ScheduledFuture<?>scheduledFuture = threadPoolTaskScheduler.schedule(scheduleTask,startTime);
        scheduledFutureMap.put(scheduleTask.getId(),scheduledFuture);
        logger.info("启动定时任务"+ scheduleTask.getId()+",执行时间为"+ startTime);
    }

    /**
     * 启动某定时任务,以固定周期运行
     * @param scheduleTask
     * @param period
     */
    public static void start(ScheduleTask scheduleTask, long period){
        if (isExist(scheduleTask.getId())){
            logger.info("启动定时任务"+ scheduleTask.getId()+"失败,任务已存在");
            return;
        }
        ScheduledFuture<?>scheduledFuture = threadPoolTaskScheduler.scheduleAtFixedRate(scheduleTask,period);
        scheduledFutureMap.put(scheduleTask.getId(),scheduledFuture);
        logger.info("启动定时任务" + scheduleTask.getId() + ",执行周期为" + period + "毫秒");
    }

    /**
     * 取消某定时任务
     * @param scheduleTask*/
    public static void cancel(ScheduleTask scheduleTask){
        ScheduledFuture<?> scheduledFuture = scheduledFutureMap.get(scheduleTask.getId());
        if(scheduledFuture != null && !scheduledFuture.isCancelled()){
            scheduledFuture.cancel(false);
        }
        scheduledFutureMap.remove(scheduleTask.getId());
        logger.info("取消定时任务"+ scheduleTask.getId());
    }
    /**
     * 修改定时任务执行时间
     * @param scheduleTask
     * @param startTime
     */
    public static void reset(ScheduleTask scheduleTask,Date startTime){
        //先取消定时任务
        String id = scheduleTask.getId();
        ScheduledFuture<?> scheduledFuture = scheduledFutureMap.get(id);
        if(scheduledFuture != null && !scheduledFuture.isCancelled()){
            scheduledFuture.cancel(false);
        }
        scheduledFutureMap.remove(id);
        //然后启动新的定时任务
        scheduledFuture = threadPoolTaskScheduler.schedule(scheduleTask,startTime);
        scheduledFutureMap.put(id,scheduledFuture);
        logger.info("重置定时任务"+ id+",执行时间为"+ startTime);
    }

    /**
     * 判断某个定时任务是否存在或已经取消
     * @param id
     */
    public static Boolean isExist(String id) {
        ScheduledFuture<?> scheduledFuture = scheduledFutureMap.get(id);
        if (scheduledFuture != null && !scheduledFuture.isCancelled()) {
            return true;
        }
        return false;
    }
}


具体的任务类

MyTask

import java.util.Date;

public class MyTask extends ScheduleTask {
    public MyTask(String id) {
        super(id);
    }

    @Override
    public void run() {
    	//todo Your operation
        System.out.println(new Date() + "任务" + this.getId() + "开始执行...hello world!");
    }
}


用法示例

import java.util.Date;

public class Main {
    public static void main(String[] args) throws Exception {
        //任务1
        ScheduleTask helloTask1 = new MyTask("task1");//new一个具体的执行任务
        ScheduleUtil.start(helloTask1, new Date(System.currentTimeMillis() + 5000));//5秒后执行一次
        ScheduleUtil.reset(helloTask1, new Date(System.currentTimeMillis() + 10000));//修改时间,10秒后执行

        //任务2
        ScheduleTask helloTask2 = new MyTask("task2");//new一个具体的执行任务
        ScheduleUtil.start(helloTask2, 2000);//每2秒执行一次
        Thread.sleep(5000);
        ScheduleUtil.cancel(helloTask2);//取消定时任务
    }
}



测试结果,如下图



在这里插入图片描述


本例无需其他任何配置,简单易用



需用到的包为:


commons-logging.jar

spring-beans

spring-context

spring-core



版权声明:本文为weixin_44248490原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。