• Spring设置动态定时任务


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

    在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分钟后取消任务。

    执行结果见下:

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

    在trigger中会根据Cron将下一次执行时间,在此次执行后设置,所以如果要动态改变执行时间,需要先取消任务(清空任务BlockQueue)。

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

    代码见下:

    @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中宏就可以方法也是一种数据。

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

  • 相关阅读:
    单词统计
    团队项目介绍--“益青春APP”
    团队项目 NABCD介绍
    兰猪耳
    薄雪万年草
    佛甲草
    针叶天蓝绣球
    白芨
    萱草
    吉祥草
  • 原文地址:https://www.cnblogs.com/CaesarLinsa/p/8197576.html
Copyright © 2020-2023  润新知