Spring设置动态定时任务

1.在Spring中常常会用到定时任务,通常会在业务方法上使用@Schedule(cron="定时执行规则"),没法实现从前台动态设置定时任务。java

在java中固定频率的任务使用ScheduleExecutorService对象来执行,ScheduleAtFixedRate固定频率执行任务和scheduleWithFixedDelay固定延迟后执行任务。编程

private static SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

    public static void main(String[] args){

     ScheduledExecutorService  scheduleTask= Executors.newScheduledThreadPool(1);

     ScheduledFuture<?> scheduledFuture = scheduleTask.scheduleAtFixedRate(() -> {

      System.out.println("每隔10秒执行一次"+dateFormat.format(new Date()));

     }, 0, 10, TimeUnit.SECONDS);


     scheduleTask.schedule(() -> {

      System.out.println(dateFormat.format(new Date())+"取消定时执行任务");
      scheduledFuture.cancel(true);

     },60,TimeUnit.SECONDS);


    }

在固定频率,每隔10秒执行一次,1分钟后取消任务。ide

执行结果见下:函数式编程

在Spring-context中,提供丰富化的ThreadPoolScheduleTask对象和Trigger触发器,能够很方便地设置任务的执行时间。函数

在trigger中会根据Cron将下一次执行时间,在这次执行后设置,因此若是要动态改变执行时间,须要先取消任务(清空任务BlockQueue)。this

根据上次执行时间和cron设置TriggerContext中的执行时间,保证设置与执行的同步一致性。spa

代码见下:code

@Component
public class DynamicScheduledTask {

    @Autowired
    private ThreadPoolTaskScheduler taskScheduler;

    private ScheduledFuture future;

    private static SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

    private  String  cron = "";


    public void setCron(final String cron) {
        this.cron = cron;
        stopScheduleTask();

        future=taskScheduler.schedule(new Runnable() {
            @Override
            public void run() {
                // 定时任务的业务逻辑
                System.out.println("动态修改定时任务cron参数,当前时间:" + dateFormat.format(new Date()));
            }
        }, new Trigger() {
            @Override
            public Date nextExecutionTime(TriggerContext triggerContext) {
                // 定时任务触发,可修改定时任务的执行周期
                if ("".equals(cron) || cron == null)
                    return null;
                CronTrigger trigger = new CronTrigger(cron);
                Date nextExecDate =trigger.nextExecutionTime(triggerContext);
                return nextExecDate;
            }});

    }

    public void stopScheduleTask(){

        if(future !=null) {
            future.cancel(true);
        }
    }


}

在这种回调中执行业务任务的方法中,能够看出java的缺陷,并不能将方法做为参数进行传递。在最古老的lisp中宏就能够方法也是一种数据。orm

在java 1.8中出现函数式编程,用JDK的ScheduleExecutorService使用了函数式,对比发现其实差异并非很大,只是一种简化。对象

相关文章
相关标签/搜索