java定時器的使用(Timer)
1、在應用開發中,常常須要一些周期性的操作,比方每5分鐘運行某一操作等。
對于這種操作最方便、高效的實現方式就是使用java.util.Timer工具類。
private java.util.Timer timer;
timer = new Timer(true);
timer.schedule(
new java.util.TimerTask() { public void run()
{ //server.checkNewMail(); 要操作的方法} }, 0, 5*60*1000);
第一個參數是要操作的方法,第二個參數是要設定延遲的時間,第三個參
數是周期的設定,每隔多長時間運行該操作。
使用這幾行代碼之后,Timer本身會每隔5分鐘調用一遍
server.checkNewMail()方法,不須要自己啟動線程。Timer本身也是多線程同
步的,多個線程能夠共用一個Timer,不須要外部的同步代碼。
2、
(1)Timer.schedule(TimerTask task,Date time)安排在制定的時間運行指定的
任務。
(2)Timer.schedule(TimerTask task,Date firstTime ,long period)安排指定
的任務在指定的時間開始進行反復的固定延遲運行.
(3)Timer.schedule(TimerTask task,long delay)安排在指定延遲后運行指定的
任務.
(4)Timer.schedule(TimerTask task,long delay,long period)安排指定的任務
從指定的延遲后開始進行反復的固定延遲運行.
(5)Timer.scheduleAtFixedRate(TimerTask task,Date firstTime,long period)
安排指定的任務在指定的時間開始進行反復的固定速率運行.
(6)Timer.scheduleAtFixedRate(TimerTask task,long delay,long period)安
排指定的任務在指定的延遲后開始進行反復的固定速率運行.
用Java Timer API 進行時間調度開發的相關注意點
java.util這個包中能夠找到Timer和TimerTask這兩個類。Timer直接從Object
繼承,它相當于一個計時器,可以用它來指定某個時間來運行一項任務,或者
每隔一定時間間隔重復運行同一個任務。創建一個Timer后,就會生成一個線程
在背后執行,來控制任務的執行。而TimerTask就是用來實現某項任務的類,
它實現了Runnable接口,因此相當于一個線程。
怎樣實現自己的任務調度?
1、繼承TimerTask,注意TimerTask是實現Runnable接口的,因此僅僅要重載run()
方法就可以。
2、創建Timer對象,調用schedule()方法。
相關注意點分析:
1、任務調度要優先考慮實時保證
因為Java的天性,而且在開發JDK的過程中要考慮到不同平臺,而不同平臺的
線程調度機制是不同的,因此各種平臺下JVM 的線程調度機制也是不一致的。
從而Timer不能保證任務在所指定的時間內運行。另外因為TimerTask是實現
Runnable接口的,在TimerTask被放進線程隊列睡眠一段時間(wait)之后,
當到了指定的該喚起該TimerTask時,因為運行的確切時機取決于JVM的調度策
略和當前還有多少線程在等待CPU處理。因此就不能保證任務在所指定的時間
內運行。通常在例如以下兩種情況下導致任務延遲運行:
(1)、有大量線程在等待運行
(2)、GC機制的影響導致延遲
這也是為什么在Timer API中存在兩組調度方法的原因。即:
(1)、schedule()
用固定延遲調度。使用本方法時,在任務運行中的每個延遲會傳播到興許的任
務的運行。
(2)、scheduleAsFixedRate()
用固定比率調度。使用本方法時,全部興許運行依據初始運行的時間進行調度,
從而希望減小延遲。
詳細使用哪一個方法取決于哪些參數對你的程序或系統更重要。
2、每一個Timer對象要在后臺啟動一個線程。這樣的性質在一些托管的環境下不推
薦使用,比方在應用server中。由于這些線程不在容器的控制范圍之內了。
詳細Java API 中的Timer 類和TimerTask類的描寫敘述例如以下:
java.util
類Timer
java.lang.Object
java.util.Timer
public class Timer
extends Object
一種線程設施,用于安排以后在后臺線程中運行的任務。可安排任務運行一次,
或者定期反復運行。
與每一個Timer 對象相相應的是單個后臺線程,用于順序地運行全部計時器任務。
計時器任務應該迅速完畢。假設完畢某個計時器任務的時間太長,那么它會“獨
占”計時器的任務運行線程。因此,這就可能延遲興許任務的運行,而這些任務
就可能“堆在一起”,而且在上述令人討厭的任務終于完畢時才可以被高速連續
地運行。
對Timer 對象最后的引用完畢后,而且全部未處理的任務都已運行完畢后,計
時器的任務運行線程會正常終止(而且成為垃圾回收的對象)。可是這可能要非常
長時間后才發生。默認情況下,任務執行線程并不作為守護線程來執行,所以
它可以阻止應用程序終止。假設調用方想要高速終止計時器的任務運行線程,那
么調用方應該調用計時器的cancel 方法。
假設意外終止了計時器的任務運行線程,比如調用了它的stop 方法,那么全部
以后對該計時器安排任務的嘗試都將導致IllegalStateException,就好像調用
了計時器的cancel 方法一樣。
此類是線程安全的:多個線程能夠共享單個Timer 對象而無需進行外部同步。
此類不提供實時保證:它使用Object.wait(long) 方法來安排任務。
實現注意事項:此類可擴展到大量同一時候安排的任務(存在數千個都沒有問題)。
在內部,它使用二進制堆來表示其任務隊列,所以安排任務的開銷是O(log n),
當中n 是同一時候安排的任務數。
實現注意事項:全部構造方法都啟動計時器線程。
從下面版本號開始:
1.3
另請參見:
TimerTask, Object.wait(long)
構造方法摘要
Timer()
創建一個新計時器。
Timer(boolean isDaemon)
創建一個新計時器,能夠指定其相關的線程作為守護程序執行。
Timer(String name)
創建一個新計時器,其相關的線程具有指定的名稱。
Timer(String name, boolean isDaemon)
創建一個新計時器,其相關的線程具有指定的名稱,而且能夠指定作為守護程序運
行。
方法摘要
void cancel()
終止此計時器,丟棄全部當前已安排的任務。
int purge()
從此計時器的任務隊列中移除全部已取消的任務。
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)
安排指定的任務從指定的延遲后開始進行反復的固定延遲運行。
void scheduleAtFixedRate(TimerTask task, Date firstTime, long period)
安排指定的任務在指定的時間開始進行反復的固定速率運行。
void scheduleAtFixedRate(TimerTask task, long delay, long period)
安排指定的任務在指定的延遲后開始進行反復的固定速率運行。
從類java.lang.Object 繼承的方法
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
構造方法具體信息
Timer
public Timer()
創建一個新計時器。相關的線程不作為守護程序執行。
另請參見:
Thread, cancel()
Timer
public Timer(boolean isDaemon)
創建一個新計時器,能夠指定其相關的線程作為守護程序執行。假設計時器將用于
安排反復的“維護活動”,則調用守護線程,在應用程序執行期間必須調用守護線程,
可是該操作不應延長程序的生命周期。
參數:
isDaemon - 假設應該將相關的線程作為守護程序執行,則為true。
另請參見:
Thread, cancel()
Timer
public Timer(String name)
創建一個新計時器,其相關的線程具有指定的名稱。相關的線程不作為守護程序運
行。
參數:
name - 相關線程的名稱。
拋出:
NullPointerException - 假設name 為null。
從下面版本號開始:
1.5
另請參見:
Thread.getName(), Thread.isDaemon()
Timer
public Timer(String name,
boolean isDaemon)
創建一個新計時器,其相關的線程具有指定的名稱,而且能夠指定作為守護程序運
行。
參數:
name - 相關線程的名稱。
isDaemon - 假設應該將相關的線程作為守護程序執行,則為true。
拋出:
NullPointerException - 假設name 為null。
從下面版本號開始:
1.5
另請參見:
Thread.getName(), Thread.isDaemon()
方法具體信息
schedule
public void schedule(TimerTask task,
long delay)
安排在指定延遲后運行指定的任務。
參數:
task - 所要安排的任務。
delay - 運行任務前的延遲時間,單位是毫秒。
拋出:
IllegalArgumentException - 假設delay 是負數, 或者delay +
System.currentTimeMillis() 是負數。
IllegalStateException - 假設已經安排或取消了任務,或者已經取消計時器。
schedule
public void schedule(TimerTask task,
Date time)
安排在指定的時間運行指定的任務。假設此時間已過去,則安排馬上運行該任務。
參數:
task - 所要安排的任務。
time - 運行任務的時間。
拋出:
IllegalArgumentException - 假設time.getTime() 是負數。
IllegalStateException - 假設已經安排或取消了任務,已經取消了計時器,或者計時
器線程已終止。
schedule
public void schedule(TimerTask task,
long delay,
long period)
安排指定的任務從指定的延遲后開始進行反復的固定延遲運行。以近似固定的時間
間隔(由指定的周期分隔)進行興許運行。
在固定延遲運行中,依據前一次運行的實際運行時間來安排每次運行。如
果因為不論什么原因(如垃圾回收或其它后臺活動)而延遲了某次運行,則后
續運行也將被延遲。從長期來看,運行的頻率一般要稍慢于指定周期的倒
數(假定Object.wait(long) 所依靠的系統時鐘是準確的)。
固定延遲執行適用于那些須要“平穩”執行的反復活動。換句話說,它適
用于在短期執行中保持頻率準確要比在長期執行中更為重要的活動。這包
括大多數動畫任務,如以固定時間間隔閃爍的光標。這還包含為響應人類
活動所運行的固定活動,如在按住鍵時自己主動反復輸入字符。
參數:
task - 所要安排的任務。
delay - 運行任務前的延遲時間,單位是毫秒。
period - 運行各興許任務之間的時間間隔,單位是毫秒。
拋出:
IllegalArgumentException - 假設delay 是負數, 或者delay +
System.currentTimeMillis() 是負數。
IllegalStateException - 假設已經安排或取消了任務,已經取消了計時器,或者計時
器線程已終止。
schedule
public void schedule(TimerTask task,
Date firstTime,
long period)
安排指定的任務在指定的時間開始進行反復的固定延遲運行。以近似固定的時間間
隔(由指定的周期分隔)進行興許運行。
在固定延遲運行中,依據前一次運行的實際運行時間來安排每次運行。如
果因為不論什么原因(如垃圾回收或其它后臺活動)而延遲了某次運行,則后
續運行也將被延遲。在長期運行中,運行的頻率一般要稍慢于指定周期的
倒數(假定Object.wait(long) 所依靠的系統時鐘是準確的)。
固定延遲運行適用于那些須要“平穩”運行的反復運行活動。換句話說,
它適用于在短期執行中保持頻率準確要比在長期執行中更為重要的活動。
這包含大多數動畫任務,如以固定時間間隔閃爍的光標。這還包含為響應
人類活動所運行的固定活動,如在按住鍵時自己主動反復輸入字符。
參數:
task - 所要安排的任務。
firstTime - 首次運行任務的時間。
period - 運行各興許任務之間的時間間隔,單位是毫秒。
拋出:
IllegalArgumentException - 假設time.getTime() 是負數。
IllegalStateException - 假設已經安排或取消了任務,已經取消了計時器,或者計時
器線程已終止。
scheduleAtFixedRate
public void scheduleAtFixedRate(TimerTask task,
long delay,
long period)
安排指定的任務在指定的延遲后開始進行反復的固定速率運行。以近似固定的時間
間隔(由指定的周期分隔)進行興許運行。
在固定速率運行中,依據已安排的初始運行時間來安排每次運行。假設由
于不論什么原因(如垃圾回收或其它背景活動)而延遲了某次運行,則將高速
連續地出現兩次或很多其它的運行,從而使興許運行可以“追趕上來”。從長
遠來看,運行的頻率將正好是指定周期的倒數(假定Object.wait(long)
所依靠的系統時鐘是準確的)。
固定速率運行適用于那些對絕對時間敏感的反復運行活動,如每小時準
點打鐘報時,或者在每天的特定時間執行已安排的維護活動。它還適用于
那些完畢固定次數運行的總計時間非常重要的反復活動,如倒計時的計時
器,每秒鐘滴答一次,共10 秒鐘。最后,固定速率運行適用于安排多個
反復運行的計時器任務,這些任務相互之間必須保持同步。
參數:
task - 所要安排的任務。
delay - 運行任務前的延遲時間,單位是毫秒。
period - 運行各興許任務之間的時間間隔,單位是毫秒。
拋出:
IllegalArgumentException - 假設delay 是負數, 或者delay +
System.currentTimeMillis() 是負數。
IllegalStateException - 假設已經安排或取消了任務,已經取消了計時器,或者計時
器線程已終止。
scheduleAtFixedRate
public void scheduleAtFixedRate(TimerTask task,
Date firstTime,
long period)
安排指定的任務在指定的時間開始進行反復的固定速率運行。以近似固定的時間間
隔(由指定的周期分隔)進行興許運行。
在固定速率運行中,相對于已安排的初始運行時間來安排每次運行。假設
因為不論什么原因(如垃圾回收或其它背景活動)而延遲了某次運行,則將快
速連續地出現兩次或很多其它次運行,從而使興許運行可以趕上來。從長遠來
看,運行的頻率將正好是指定周期的倒數(假定Object.wait(long) 所
依靠的系統時鐘是準確的)。
固定速率運行適用于那些對絕對時間敏感的反復運行活動,如每小時準
點打鐘報時,或者在每天的特定時間執行已安排的維護活動。它還適用于
那些完畢固定次數運行的總計時間非常重要的反復活動,如倒計時的計時
器,每秒鐘滴答一次,共10 秒鐘。最后,固定速率運行適用于安排多次
反復運行的計時器任務,這些任務相互之間必須保持同步。
參數:
task - 所要安排的任務。
firstTime - 首次運行任務的時間。
period - 運行各興許任務之間的時間間隔,單位是毫秒。
拋出:
IllegalArgumentException - 假設time.getTime() 是負數。
IllegalStateException - 假設已經安排或取消了任務,已經取消了計時器,或者計時
器線程已終止。
cancel
public void cancel()
終止此計時器,丟棄全部當前已安排的任務。這不會干擾當前正在運行的任務(如
果存在)。一旦終止了計時器,那么它的運行線程也會終止,而且無法依據它安排更
多的任務。
注意,在此計時器調用的計時器任務的run 方法內調用此方法,就能夠
絕對確保正在運行的任務是此計時器所運行的最后一個任務。
能夠反復調用此方法;可是第二次和興許調用無效。
purge
public int purge()
從此計時器的任務隊列中移除全部已取消的任務。調用此方法對計時器的行為沒有
影響,可是將無法引用隊列中已取消的任務。假設沒有對這些任務的外部引用,則
它們就成為垃圾回收的合格對象。
多數程序無需調用此方法。它設計用于一些罕見的應用程序,這些程序可
取消大量的任務。調用此方法要以時間來換取空間:此方法的執行時可能
與n + c log n 呈正比,當中n 是隊列中的任務數,而c 是取消的任
務數。
注意,從此計時器上所安排的任務中調用此方法是同意的。
返回:
從隊列中移除的任務數。
從下面版本號開始:
1.5
以下是TimerTask類的介紹
java.util
類TimerTask
java.lang.Object
java.util.TimerTask
全部已實現的接口:
Runnable
public abstract class TimerTask
extends Object
implements Runnable
由Timer 安排為一次運行或反復運行的任務。
從下面版本號開始:
1.3
另請參見:
Timer
構造方法摘要
protected TimerTask()
創建一個新的計時器任務。
方法摘要
boolean cancel()
取消此計時器任務。
abstract void run()
此計時器任務要運行的操作。
long scheduledExecutionTime()
返回此任務近期實際運行的安排運行時間。
從類java.lang.Object 繼承的方法
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
構造方法具體信息
TimerTask
protected TimerTask()
創建一個新的計時器任務。
方法具體信息
run
public abstract void run()
此計時器任務要運行的操作。
指定者:
接口Runnable 中的run
另請參見:
Thread.run()
cancel
public boolean cancel()
取消此計時器任務。假設任務安排為一次執行且還未執行,或者尚未安排,則永遠
不會執行。假設任務安排為反復執行,則永遠不會再執行。(假設發生此調用時任務
正在執行,則任務將執行完,但永遠不會再執行。)
注意,從反復的計時器任務的run 方法中調用此方法絕對保證計時器任
務永遠不會再執行。
此方法能夠重復調用;第二次和以后的調用無效。
返回:
假設此任務安排為一次運行且尚未運行,或者此任務安排為反復運行,則返回true。
假設此任務安排為一次執行且已經執行,或者此任務尚未安排,或者此任務已經取
消,則返回false。(一般來說,假設此方法阻止發生一個或多個安排運行,則返回
true。)
scheduledExecutionTime
public long scheduledExecutionTime()
返回此任務近期實際運行的安排運行時間。(假設在任務運行過程中調用此方法,
則返回值為此任務運行的安排運行時間。)
通常從一個任務的run 方法中調用此方法,以確定當前任務運行能否
充分及時地保證完畢安排活動:
public void run() {
if (System.currentTimeMillis() - scheduledExecutionTime()
>=
MAX_TARDINESS)
return; // Too late; skip this execution.
// Perform the task
}
通常,此方法不與固定延遲運行的反復任務一起使用,由于其安排運行時間同意
隨時間浮動,所以毫無意義。
返回:
近期發生此任務運行安排的時間,採用Date.getTime() 返回的格式。假設任務已開
始其首次運行,則返回值不確定。
另請參見:
Date.getTime()
?
?