自定義spring定時器
阿新 • • 發佈:2017-09-08
() spl public == integer service upd imei second
package com.wjz.quartz; import java.util.concurrent.Executors; public class QuartzDemo { public static void main(String[] args) throws Exception { new MyRunnable(Executors.newSingleThreadScheduledExecutor()).schedule(); // 這裏讓main線程睡眠是因為如果主線程執行完了MyRunnable對象就被銷毀了實驗效果無法展現Thread.sleep(1000*60*5); } }
我可以看到初始化了一個任務線程延遲調度器ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();註入到了Runnable中
核心類MyRunnable實現了Runnable和ScheduledFuture接口
run方法中執行了任務調度
package com.wjz.quartz; import java.util.Date; import java.util.concurrent.Delayed;import java.util.concurrent.ExecutionException; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.springframework.scheduling.support.SimpleTriggerContext;class MyRunnable implements Runnable, ScheduledFuture<Object> { private final ScheduledExecutorService executor; private final MyTrigger trigger = new MyTrigger(); private final SimpleTriggerContext triggerContext = new SimpleTriggerContext(); private final Object triggerContextMonitor = new Object(); private ScheduledFuture<?> currentFuture; private Date scheduledExecutionTime; public MyRunnable(ScheduledExecutorService executor) { this.executor = executor; } public ScheduledFuture<?> schedule() { synchronized (triggerContextMonitor) {
// 獲得計劃中的下一個執行時間 this.scheduledExecutionTime = trigger.nextExecutionTime(triggerContext); long delay = scheduledExecutionTime.getTime() - System.currentTimeMillis();
// 延時任務調度 this.currentFuture = executor.schedule(this, delay, TimeUnit.MILLISECONDS); return this; } } public void run() { Date actualExecutionTime = new Date(); System.out.println("------調用定時方法------"); Date completionTime = new Date(); synchronized (triggerContextMonitor) { triggerContext.update(scheduledExecutionTime, actualExecutionTime, completionTime); if (!this.currentFuture.isCancelled()) { schedule(); } } } public boolean cancel(boolean mayInterruptIfRunning) { synchronized (this.triggerContextMonitor) { return this.currentFuture.cancel(mayInterruptIfRunning); } } public boolean isCancelled() { synchronized (this.triggerContextMonitor) { return this.currentFuture.isCancelled(); } } public boolean isDone() { synchronized (this.triggerContextMonitor) { return this.currentFuture.isDone(); } } public Object get() throws InterruptedException, ExecutionException { ScheduledFuture<?> curr; synchronized (this.triggerContextMonitor) { curr = this.currentFuture; } return curr.get(); } public Object get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { ScheduledFuture<?> curr; synchronized (this.triggerContextMonitor) { curr = this.currentFuture; } return curr.get(timeout, unit); } public long getDelay(TimeUnit unit) { ScheduledFuture<?> curr; synchronized (this.triggerContextMonitor) { curr = this.currentFuture; } return curr.getDelay(unit); } public int compareTo(Delayed other) { if (this == other) { return 0; } long diff = getDelay(TimeUnit.MILLISECONDS) - other.getDelay(TimeUnit.MILLISECONDS); return (diff == 0 ? 0 : ((diff < 0)? -1 : 1)); } }
觸發器主要是返回觸發時間
package com.wjz.quartz; import java.util.Date; import org.springframework.scheduling.Trigger; import org.springframework.scheduling.TriggerContext; public class MyTrigger implements Trigger { private MySequence sequence = new MySequence(); public Date nextExecutionTime(TriggerContext triggerContext) { Date date = triggerContext.lastCompletionTime(); if (date == null) { date = new Date(); } return sequence.next(date); } }
計劃時間表生成器主要是生成觸發時間和返回下一個觸發時間
package com.wjz.quartz; import java.util.BitSet; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.TimeZone; public class MySequence { private final BitSet seconds = new BitSet(60); MySequence() { setNumber(seconds, "0/5", 0, 60); } public Date next(Date date) { Calendar calendar = new GregorianCalendar(); calendar.setTime(date); calendar.setTimeZone(TimeZone.getDefault()); // 重置毫秒數 calendar.set(Calendar.MILLISECOND, 0); long originalTimestamp = calendar.getTimeInMillis(); doNext(calendar); if (calendar.getTimeInMillis() == originalTimestamp) { // 日歷時間剛好到了原始時間戳時間,加一秒 calendar.add(Calendar.SECOND, 1); doNext(calendar); } return calendar.getTime(); } private void doNext(Calendar calendar) { int second = calendar.get(Calendar.SECOND); int nextSecond = seconds.nextSetBit(second); if (nextSecond == -1) { // 加一分鐘 calendar.add(Calendar.MINUTE, 1); // 重置秒數 calendar.set(Calendar.SECOND, 0); nextSecond = seconds.nextSetBit(0); } if (second != nextSecond) { calendar.set(Calendar.SECOND, nextSecond); } } private static void setNumber(BitSet bitSet, String field, int min, int max) { String[] fields = field.split("/"); // 0, 5 int[] split = new int[2]; int start = split[0] = Integer.valueOf(fields[0]); int grow = split[1] = Integer.valueOf(fields[1]); int[] range = new int[2]; range[0] = split[0]; int end = range[1] = max - 1; for (int i = start; i < end; i += grow) { bitSet.set(i); } } }
自定義spring定時器