網上找了找,java寫定時任務的方法很多,架構也有很多提供了定時任務介面,對於初學java程式員來說,還是考慮JDK裡面的內容比較適合。
先看原理:
JDK中,定時器任務的執行需要兩個基本的類:
java.util.Timer;
java.util.TimerTask;
要運行一個定時任務,最基本的步驟如下:
1、建立一個要執行的任務TimerTask。
2、建立一個Timer執行個體,通過Timer提供的schedule()方法,將 TimerTask加入到定時器Timer中,同時設定執行的規則即可。
當程式執行了Timer初始化代碼後,Timer定時任務就會按照設定去執行。
Timer中的schedule()方法是有多種重載格式的,以適應不同的情況。該方法的格式如下:
void schedule(TimerTask task, Date time)
安排在指定的時間執行指定的任務。
void schedule(TimerTask task, Date firstTime, long period)
安排指定的任務在指定的時間開始進行重複的固定順延強制。
void schedule(TimerTask task, long delay)
安排在指定延遲後執行指定的任務。
void schedule(TimerTask task, long delay, long period)
安排指定的任務從指定的延遲後開始進行重複的固定順延強制。
Timer是安全執行緒的,此類可擴充到大量同時安排的任務(存在數千個都沒有問題)。其所有構造方法都啟動計時器線程。可以調用cancel() 終止此計時器,丟棄所有當前已安排的任務。purge()從此計時器的任務隊列中移除所有已取消的任務。此類不提供即時保證:它使用 Object.wait(long) 方法來安排任務。
TimerTask是一個抽象類別,由 Timer 安排為一次執行或重複執行的任務。它有一個抽象方法run()----計時器任務要執行的操作。因此,每個具體的任務類都必須繼承TimerTask類,並且重寫run()方法。另外它還有兩個非抽象的方法:
boolean cancel()
取消此計時器任務。
long scheduledExecutionTime()
返回此任務最近實際 執行的安排 執行時間。
再看源碼:
package nov;import java.util.Date;import java.util.Timer;import java.util.TimerTask;/** * * * <p> * Title: 定時任務測試代碼 /p> * * <p> * Description: 樣本 業務類 * </p> * * <p> * Copyright: Copyright (c) 2012 * </p> * * * @author dml@2012-11-29 * @version 1.0 */public class TimerTest extends TimerTask {/** * 此計時器任務要執行的操作。 */public void run() {Date executeTime = new Date(this.scheduledExecutionTime());System.out.println("本次任務執行的時間是" + executeTime);} public static void main(String[] args) { Timer timer = new Timer(); TimerTask task = new TimerTest(); timer.schedule(task, 500L, 1000L); }}
執行結果:
本次任務執行的時間是Thu Nov 29 10:39:38 CST 2012本次任務執行的時間是Thu Nov 29 10:39:39 CST 2012本次任務執行的時間是Thu Nov 29 10:39:40 CST 2012本次任務執行的時間是Thu Nov 29 10:39:41 CST 2012本次任務執行的時間是Thu Nov 29 10:39:42 CST 2012本次任務執行的時間是Thu Nov 29 10:39:43 CST 2012本次任務執行的時間是Thu Nov 29 10:39:44 CST 2012本次任務執行的時間是Thu Nov 29 10:39:45 CST 2012本次任務執行的時間是Thu Nov 29 10:39:46 CST 2012本次任務執行的時間是Thu Nov 29 10:39:47 CST 2012本次任務執行的時間是Thu Nov 29 10:39:48 CST 2012本次任務執行的時間是Thu Nov 29 10:39:49 CST 2012本次任務執行的時間是Thu Nov 29 10:39:50 CST 2012本次任務執行的時間是Thu Nov 29 10:39:51 CST 2012本次任務執行的時間是Thu Nov 29 10:39:52 CST 2012本次任務執行的時間是Thu Nov 29 10:39:53 CST 2012本次任務執行的時間是Thu Nov 29 10:39:54 CST 2012本次任務執行的時間是Thu Nov 29 10:39:55 CST 2012本次任務執行的時間是Thu Nov 29 10:39:56 CST 2012本次任務執行的時間是Thu Nov 29 10:39:57 CST 2012本次任務執行的時間是Thu Nov 29 10:39:58 CST 2012本次任務執行的時間是Thu Nov 29 10:39:59 CST 2012……
分析:
上面的樣本調用的方法如下:
/** * Schedules the specified task for repeated <i>fixed-delay execution</i>, * beginning after the specified delay. Subsequent executions take place * at approximately regular intervals separated by the specified period. * * <p>In fixed-delay execution, each execution is scheduled relative to * the actual execution time of the previous execution. If an execution * is delayed for any reason (such as garbage collection or other * background activity), subsequent executions will be delayed as well. * In the long run, the frequency of execution will generally be slightly * lower than the reciprocal of the specified period (assuming the system * clock underlying <tt>Object.wait(long)</tt> is accurate). * * <p>Fixed-delay execution is appropriate for recurring activities * that require "smoothness." In other words, it is appropriate for * activities where it is more important to keep the frequency accurate * in the short run than in the long run. This includes most animation * tasks, such as blinking a cursor at regular intervals. It also includes * tasks wherein regular activity is performed in response to human * input, such as automatically repeating a character as long as a key * is held down. * * @param task task to be scheduled. * @param delay delay in milliseconds before task is to be executed. * @param period time in milliseconds between successive task executions. * @throws IllegalArgumentException if <tt>delay</tt> is negative, or * <tt>delay + System.currentTimeMillis()</tt> is negative. * @throws IllegalStateException if task was already scheduled or * cancelled, timer was cancelled, or timer thread terminated. */ public void schedule(TimerTask task, long delay, long period) { if (delay < 0) throw new IllegalArgumentException("Negative delay."); if (period <= 0) throw new IllegalArgumentException("Non-positive period."); sched(task, System.currentTimeMillis()+delay, -period); }
三個參數:任務 延時時間 連續周期
時間設定合理後調用sched方法:
/** * Schedule the specified timer task for execution at the specified * time with the specified period, in milliseconds. If period is * positive, the task is scheduled for repeated execution; if period is * zero, the task is scheduled for one-time execution. Time is specified * in Date.getTime() format. This method checks timer state, task state, * and initial execution time, but not period. * * @throws IllegalArgumentException if <tt>time()</tt> is negative. * @throws IllegalStateException if task was already scheduled or * cancelled, timer was cancelled, or timer thread terminated. */ private void sched(TimerTask task, long time, long period) { if (time < 0) throw new IllegalArgumentException("Illegal execution time."); synchronized(queue) { if (!thread.newTasksMayBeScheduled) throw new IllegalStateException("Timer already cancelled."); synchronized(task.lock) { if (task.state != TimerTask.VIRGIN) throw new IllegalStateException( "Task already scheduled or cancelled"); task.nextExecutionTime = time; task.period = period; task.state = TimerTask.SCHEDULED; } queue.add(task); if (queue.getMin() == task) queue.notify(); } }
synchronized修飾,保證安全執行緒...Timer類還有很多其他的方法,有空再一個個試試。
p.s.經常看JDK裡面的代碼,能協助養成良好的代碼注釋風格,這點很重要。
dml@2012.11.29