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

相關文章
相關標籤/搜索