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