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使用了函數式,對比發現其實差別並不是很大,只是一種簡化。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM