java定时器的使用
java定時器的使用(Timer)
1、在應(yīng)用開發(fā)中,經(jīng)常需要一些周期性的操作,比如每5分鐘執(zhí)行某一操作等。
對于這樣的操作最方便、高效的實現(xiàn)方式就是使用java.util.Timer工具類。
privatejava.util.Timer timer;
timer = newTimer(true);
timer.schedule(
newjava.util.TimerTask() { public void run()
{//server.checkNewMail();?要操作的方法} }, 0, 5*60*1000);
第一個參數(shù)是要操作的方法,第二個參數(shù)是要設(shè)定延遲的時間,第三個參
數(shù)是周期的設(shè)定,每隔多長時間執(zhí)行該操作。
使用這幾行代碼之后,Timer本身會每隔5分鐘調(diào)用一遍
server.checkNewMail()方法,不需要自己啟動線程。Timer本身也是多線程同
步的,多個線程可以共用一個Timer,不需要外部的同步代碼。
2、
(1)Timer.schedule(TimerTasktask,Date time)安排在制定的時間執(zhí)行指定的
任務(wù)。
(2)Timer.schedule(TimerTasktask,Date firstTime ,long period)安排指定
的任務(wù)在指定的時間開始進行重復(fù)的固定延遲執(zhí)行.
(3)Timer.schedule(TimerTasktask,long delay)安排在指定延遲后執(zhí)行指定的
任務(wù).
(4)Timer.schedule(TimerTasktask,long delay,long period)安排指定的任務(wù)
從指定的延遲后開始進行重復(fù)的固定延遲執(zhí)行.
(5)Timer.scheduleAtFixedRate(TimerTasktask,Date firstTime,long period)
安排指定的任務(wù)在指定的時間開始進行重復(fù)的固定速率執(zhí)行.
(6)Timer.scheduleAtFixedRate(TimerTasktask,long delay,long period)安
排指定的任務(wù)在指定的延遲后開始進行重復(fù)的固定速率執(zhí)行.
用Java Timer API?進行時間調(diào)度開發(fā)的相關(guān)注意點
java.util這個包中可以找到Timer和TimerTask這兩個類。Timer直接從Object
繼承,它相當(dāng)于一個計時器,能夠用它來指定某個時間來執(zhí)行一項任務(wù),或者
每隔一定時間間隔反復(fù)執(zhí)行同一個任務(wù)。創(chuàng)建一個Timer后,就會生成一個線程
在背后運行,來控制任務(wù)的執(zhí)行。而TimerTask就是用來實現(xiàn)某項任務(wù)的類,
它實現(xiàn)了Runnable接口,因此相當(dāng)于一個線程。
如何實現(xiàn)自己的任務(wù)調(diào)度?
1、繼承TimerTask,注意TimerTask是實現(xiàn)Runnable接口的,因此只要重載run()
方法即可。
2、創(chuàng)建Timer對象,調(diào)用schedule()方法。
相關(guān)注意點分析:
1、任務(wù)調(diào)度要優(yōu)先考慮實時保證
由于Java的天性,并且在開發(fā)JDK的過程中要考慮到不同平臺,而不同平臺的
線程調(diào)度機制是不同的,因此各種平臺下JVM?的線程調(diào)度機制也是不一致的。
從而Timer不能保證任務(wù)在所指定的時間內(nèi)執(zhí)行。另外由于TimerTask是實現(xiàn)
Runnable接口的,在TimerTask被放進線程隊列睡眠一段時間(wait)之后,
當(dāng)?shù)搅酥付ǖ脑搯酒鹪揟imerTask時,由于執(zhí)行的確切時機取決于JVM的調(diào)度策
略和當(dāng)前還有多少線程在等待CPU處理。因此就不能保證任務(wù)在所指定的時間
內(nèi)執(zhí)行。通常在如下兩種情況下導(dǎo)致任務(wù)延遲執(zhí)行:
(1)、有大量線程在等待執(zhí)行
(2)、GC機制的影響導(dǎo)致延遲
這也是為什么在Timer API中存在兩組調(diào)度方法的原因。即:
(1)、schedule()
用固定延遲調(diào)度。使用本方法時,在任務(wù)執(zhí)行中的每一個延遲會傳播到后續(xù)的任
務(wù)的執(zhí)行。
(2)、scheduleAsFixedRate()
用固定比率調(diào)度。使用本方法時,所有后續(xù)執(zhí)行根據(jù)初始執(zhí)行的時間進行調(diào)度,
從而希望減小延遲。
具體使用哪一個方法取決于哪些參數(shù)對你的程序或系統(tǒng)更重要。
2、每個Timer對象要在后臺啟動一個線程。這種性質(zhì)在一些托管的環(huán)境下不推
薦使用,比如在應(yīng)用服務(wù)器中。因為這些線程不在容器的控制范圍之內(nèi)了。
具體Java API?中的Timer?類和TimerTask類的描述如下:
java.util
類Timer
java.lang.Object
java.util.Timer
public class Timer
extends?Object
一種線程設(shè)施,用于安排以后在后臺線程中執(zhí)行的任務(wù)。可安排任務(wù)執(zhí)行一次,
或者定期重復(fù)執(zhí)行。
與每個Timer?對象相對應(yīng)的是單個后臺線程,用于順序地執(zhí)行所有計時器任務(wù)。
計時器任務(wù)應(yīng)該迅速完成。如果完成某個計時器任務(wù)的時間太長,那么它會“獨
占”計時器的任務(wù)執(zhí)行線程。因此,這就可能延遲后續(xù)任務(wù)的執(zhí)行,而這些任務(wù)
就可能“堆在一起”,并且在上述令人討厭的任務(wù)最終完成時才能夠被快速連續(xù)
地執(zhí)行。
對Timer?對象最后的引用完成后,并且所有未處理的任務(wù)都已執(zhí)行完成后,計
時器的任務(wù)執(zhí)行線程會正常終止(并且成為垃圾回收的對象)。但是這可能要很
長時間后才發(fā)生。默認(rèn)情況下,任務(wù)執(zhí)行線程并不作為守護線程來運行,所以
它能夠阻止應(yīng)用程序終止。如果調(diào)用方想要快速終止計時器的任務(wù)執(zhí)行線程,那
么調(diào)用方應(yīng)該調(diào)用計時器的cancel?方法。
如果意外終止了計時器的任務(wù)執(zhí)行線程,例如調(diào)用了它的stop?方法,那么所有
以后對該計時器安排任務(wù)的嘗試都將導(dǎo)致IllegalStateException,就好像調(diào)用
了計時器的cancel?方法一樣。
此類是線程安全的:多個線程可以共享單個Timer?對象而無需進行外部同步。
此類不提供實時保證:它使用Object.wait(long)?方法來安排任務(wù)。
實現(xiàn)注意事項:此類可擴展到大量同時安排的任務(wù)(存在數(shù)千個都沒有問題)。
在內(nèi)部,它使用二進制堆來表示其任務(wù)隊列,所以安排任務(wù)的開銷是O(log n),
其中n?是同時安排的任務(wù)數(shù)。
實現(xiàn)注意事項:所有構(gòu)造方法都啟動計時器線程。
從以下版本開始:
1.3
另請參見:
TimerTask,?Object.wait(long)
構(gòu)造方法摘要
Timer()
創(chuàng)建一個新計時器。
Timer(boolean isDaemon)
創(chuàng)建一個新計時器,可以指定其相關(guān)的線程作為守護程序運行。
Timer(String?name)
創(chuàng)建一個新計時器,其相關(guān)的線程具有指定的名稱。
Timer(String?name,boolean isDaemon)
創(chuàng)建一個新計時器,其相關(guān)的線程具有指定的名稱,并且可以指定作為守護程序運
行。
方法摘要
void?cancel()
終止此計時器,丟棄所有當(dāng)前已安排的任務(wù)。
int?purge()
從此計時器的任務(wù)隊列中移除所有已取消的任務(wù)。
void?schedule(TimerTask?task,?Date?time)
安排在指定的時間執(zhí)行指定的任務(wù)。
void?schedule(TimerTask?task,?Date?firstTime,long period)
安排指定的任務(wù)在指定的時間開始進行重復(fù)的固定延遲執(zhí)行。
void?schedule(TimerTask?task, longdelay)
安排在指定延遲后執(zhí)行指定的任務(wù)。
void?schedule(TimerTask?task, longdelay, long period)
安排指定的任務(wù)從指定的延遲后開始進行重復(fù)的固定延遲執(zhí)行。
void?scheduleAtFixedRate(TimerTask?task,?Date?firstTime,long period)
安排指定的任務(wù)在指定的時間開始進行重復(fù)的固定速率執(zhí)行。
void?scheduleAtFixedRate(TimerTask?task, longdelay, long period)
安排指定的任務(wù)在指定的延遲后開始進行重復(fù)的固定速率執(zhí)行。
從類java.lang.Object?繼承的方法
clone,?equals,?finalize,?getClass,?hashCode,?notify,?notifyAll,?toString,?wait,?wait,?wait
構(gòu)造方法詳細(xì)信息
Timer
public Timer()
創(chuàng)建一個新計時器。相關(guān)的線程不作為守護程序運行。
另請參見:
Thread,?cancel()
Timer
publicTimer(boolean isDaemon)
創(chuàng)建一個新計時器,可以指定其相關(guān)的線程作為守護程序運行。如果計時器將用于
安排重復(fù)的“維護活動”,則調(diào)用守護線程,在應(yīng)用程序運行期間必須調(diào)用守護線程,
但是該操作不應(yīng)延長程序的生命周期。
參數(shù):
isDaemon?-?如果應(yīng)該將相關(guān)的線程作為守護程序運行,則為true。
另請參見:
Thread,?cancel()
Timer
public Timer(String?name)
創(chuàng)建一個新計時器,其相關(guān)的線程具有指定的名稱。相關(guān)的線程不作為守護程序運
行。
參數(shù):
name?-?相關(guān)線程的名稱。
拋出:
NullPointerException?-?如果name?為null。
從以下版本開始:
1.5
另請參見:
Thread.getName(),?Thread.isDaemon()
Timer
public Timer(String?name,
boolean isDaemon)
創(chuàng)建一個新計時器,其相關(guān)的線程具有指定的名稱,并且可以指定作為守護程序運
行。
參數(shù):
name?-?相關(guān)線程的名稱。
isDaemon?-?如果應(yīng)該將相關(guān)的線程作為守護程序運行,則為true。
拋出:
NullPointerException?-?如果name?為null。
從以下版本開始:
1.5
另請參見:
Thread.getName(),?Thread.isDaemon()
方法詳細(xì)信息
schedule
public voidschedule(TimerTask?task,
long delay)
安排在指定延遲后執(zhí)行指定的任務(wù)。
參數(shù):
task?-?所要安排的任務(wù)。
delay?-?執(zhí)行任務(wù)前的延遲時間,單位是毫秒。
拋出:
IllegalArgumentException?-?如果delay?是負(fù)數(shù), 或者delay +
System.currentTimeMillis()?是負(fù)數(shù)。
IllegalStateException?-?如果已經(jīng)安排或取消了任務(wù),或者已經(jīng)取消計時器。
schedule
public voidschedule(TimerTask?task,
Date?time)
安排在指定的時間執(zhí)行指定的任務(wù)。如果此時間已過去,則安排立即執(zhí)行該任務(wù)。
參數(shù):
task?-?所要安排的任務(wù)。
time?-?執(zhí)行任務(wù)的時間。
拋出:
IllegalArgumentException?-?如果time.getTime()?是負(fù)數(shù)。
IllegalStateException?-?如果已經(jīng)安排或取消了任務(wù),已經(jīng)取消了計時器,或者計時
器線程已終止。
schedule
public voidschedule(TimerTask?task,
long delay,
long period)
安排指定的任務(wù)從指定的延遲后開始進行重復(fù)的固定延遲執(zhí)行。以近似固定的時間
間隔(由指定的周期分隔)進行后續(xù)執(zhí)行。
在固定延遲執(zhí)行中,根據(jù)前一次執(zhí)行的實際執(zhí)行時間來安排每次執(zhí)行。如
果由于任何原因(如垃圾回收或其他后臺活動)而延遲了某次執(zhí)行,則后
續(xù)執(zhí)行也將被延遲。從長期來看,執(zhí)行的頻率一般要稍慢于指定周期的倒
數(shù)(假定Object.wait(long)?所依靠的系統(tǒng)時鐘是準(zhǔn)確的)。
固定延遲執(zhí)行適用于那些需要“平穩(wěn)”運行的重復(fù)活動。換句話說,它適
用于在短期運行中保持頻率準(zhǔn)確要比在長期運行中更為重要的活動。這包
括大多數(shù)動畫任務(wù),如以固定時間間隔閃爍的光標(biāo)。這還包括為響應(yīng)人類
活動所執(zhí)行的固定活動,如在按住鍵時自動重復(fù)輸入字符。
參數(shù):
task?-?所要安排的任務(wù)。
delay?-?執(zhí)行任務(wù)前的延遲時間,單位是毫秒。
period?-?執(zhí)行各后續(xù)任務(wù)之間的時間間隔,單位是毫秒。
拋出:
IllegalArgumentException?-?如果delay?是負(fù)數(shù), 或者delay +
System.currentTimeMillis()?是負(fù)數(shù)。
IllegalStateException?-?如果已經(jīng)安排或取消了任務(wù),已經(jīng)取消了計時器,或者計時
器線程已終止。
schedule
public voidschedule(TimerTask?task,
Date?firstTime,
long period)
安排指定的任務(wù)在指定的時間開始進行重復(fù)的固定延遲執(zhí)行。以近似固定的時間間
隔(由指定的周期分隔)進行后續(xù)執(zhí)行。
在固定延遲執(zhí)行中,根據(jù)前一次執(zhí)行的實際執(zhí)行時間來安排每次執(zhí)行。如
果由于任何原因(如垃圾回收或其他后臺活動)而延遲了某次執(zhí)行,則后
續(xù)執(zhí)行也將被延遲。在長期運行中,執(zhí)行的頻率一般要稍慢于指定周期的
倒數(shù)(假定Object.wait(long)?所依靠的系統(tǒng)時鐘是準(zhǔn)確的)。
固定延遲執(zhí)行適用于那些需要“平穩(wěn)”運行的重復(fù)執(zhí)行活動。換句話說,
它適用于在短期運行中保持頻率準(zhǔn)確要比在長期運行中更為重要的活動。
這包括大多數(shù)動畫任務(wù),如以固定時間間隔閃爍的光標(biāo)。這還包括為響應(yīng)
人類活動所執(zhí)行的固定活動,如在按住鍵時自動重復(fù)輸入字符。
參數(shù):
task?-?所要安排的任務(wù)。
firstTime?-?首次執(zhí)行任務(wù)的時間。
period?-?執(zhí)行各后續(xù)任務(wù)之間的時間間隔,單位是毫秒。
拋出:
IllegalArgumentException?-?如果time.getTime()?是負(fù)數(shù)。
IllegalStateException?-?如果已經(jīng)安排或取消了任務(wù),已經(jīng)取消了計時器,或者計時
器線程已終止。
scheduleAtFixedRate
public voidscheduleAtFixedRate(TimerTask?task,
long delay,
long period)
安排指定的任務(wù)在指定的延遲后開始進行重復(fù)的固定速率執(zhí)行。以近似固定的時間
間隔(由指定的周期分隔)進行后續(xù)執(zhí)行。
在固定速率執(zhí)行中,根據(jù)已安排的初始執(zhí)行時間來安排每次執(zhí)行。如果由
于任何原因(如垃圾回收或其他背景活動)而延遲了某次執(zhí)行,則將快速
連續(xù)地出現(xiàn)兩次或更多的執(zhí)行,從而使后續(xù)執(zhí)行能夠“追趕上來”。從長
遠(yuǎn)來看,執(zhí)行的頻率將正好是指定周期的倒數(shù)(假定Object.wait(long)
所依靠的系統(tǒng)時鐘是準(zhǔn)確的)。
固定速率執(zhí)行適用于那些對絕對時間敏感的重復(fù)執(zhí)行活動,如每小時準(zhǔn)
點打鐘報時,或者在每天的特定時間運行已安排的維護活動。它還適用于
那些完成固定次數(shù)執(zhí)行的總計時間很重要的重復(fù)活動,如倒計時的計時
器,每秒鐘滴答一次,共10?秒鐘。最后,固定速率執(zhí)行適用于安排多個
重復(fù)執(zhí)行的計時器任務(wù),這些任務(wù)相互之間必須保持同步。
參數(shù):
task?-?所要安排的任務(wù)。
delay?-?執(zhí)行任務(wù)前的延遲時間,單位是毫秒。
period?-?執(zhí)行各后續(xù)任務(wù)之間的時間間隔,單位是毫秒。
拋出:
IllegalArgumentException?-?如果delay?是負(fù)數(shù), 或者delay +
System.currentTimeMillis()?是負(fù)數(shù)。
IllegalStateException?-?如果已經(jīng)安排或取消了任務(wù),已經(jīng)取消了計時器,或者計時
器線程已終止。
scheduleAtFixedRate
public voidscheduleAtFixedRate(TimerTask?task,
Date?firstTime,
long period)
安排指定的任務(wù)在指定的時間開始進行重復(fù)的固定速率執(zhí)行。以近似固定的時間間
隔(由指定的周期分隔)進行后續(xù)執(zhí)行。
在固定速率執(zhí)行中,相對于已安排的初始執(zhí)行時間來安排每次執(zhí)行。如果
由于任何原因(如垃圾回收或其他背景活動)而延遲了某次執(zhí)行,則將快
速連續(xù)地出現(xiàn)兩次或更多次執(zhí)行,從而使后續(xù)執(zhí)行能夠趕上來。從長遠(yuǎn)來
看,執(zhí)行的頻率將正好是指定周期的倒數(shù)(假定Object.wait(long)?所
依靠的系統(tǒng)時鐘是準(zhǔn)確的)。
固定速率執(zhí)行適用于那些對絕對時間敏感的重復(fù)執(zhí)行活動,如每小時準(zhǔn)
點打鐘報時,或者在每天的特定時間運行已安排的維護活動。它還適用于
那些完成固定次數(shù)執(zhí)行的總計時間很重要的重復(fù)活動,如倒計時的計時
器,每秒鐘滴答一次,共10?秒鐘。最后,固定速率執(zhí)行適用于安排多次
重復(fù)執(zhí)行的計時器任務(wù),這些任務(wù)相互之間必須保持同步。
參數(shù):
task?-?所要安排的任務(wù)。
firstTime?-?首次執(zhí)行任務(wù)的時間。
period?-?執(zhí)行各后續(xù)任務(wù)之間的時間間隔,單位是毫秒。
拋出:
IllegalArgumentException?-?如果time.getTime()?是負(fù)數(shù)。
IllegalStateException?-?如果已經(jīng)安排或取消了任務(wù),已經(jīng)取消了計時器,或者計時
器線程已終止。
cancel
public voidcancel()
終止此計時器,丟棄所有當(dāng)前已安排的任務(wù)。這不會干擾當(dāng)前正在執(zhí)行的任務(wù)(如
果存在)。一旦終止了計時器,那么它的執(zhí)行線程也會終止,并且無法根據(jù)它安排更
多的任務(wù)。
注意,在此計時器調(diào)用的計時器任務(wù)的run?方法內(nèi)調(diào)用此方法,就可以
絕對確保正在執(zhí)行的任務(wù)是此計時器所執(zhí)行的最后一個任務(wù)。
可以重復(fù)調(diào)用此方法;但是第二次和后續(xù)調(diào)用無效。
purge
public int purge()
從此計時器的任務(wù)隊列中移除所有已取消的任務(wù)。調(diào)用此方法對計時器的行為沒有
影響,但是將無法引用隊列中已取消的任務(wù)。如果沒有對這些任務(wù)的外部引用,則
它們就成為垃圾回收的合格對象。
多數(shù)程序無需調(diào)用此方法。它設(shè)計用于一些罕見的應(yīng)用程序,這些程序可
取消大量的任務(wù)。調(diào)用此方法要以時間來換取空間:此方法的運行時可能
與n + c log n?呈正比,其中n?是隊列中的任務(wù)數(shù),而c?是取消的任
務(wù)數(shù)。
注意,從此計時器上所安排的任務(wù)中調(diào)用此方法是允許的。
返回:
從隊列中移除的任務(wù)數(shù)。
從以下版本開始:
1.5
下面是TimerTask類的介紹
java.util
類TimerTask
java.lang.Object
java.util.TimerTask
所有已實現(xiàn)的接口:
Runnable
public abstractclass TimerTask
extends?Object
implements?Runnable
由Timer?安排為一次執(zhí)行或重復(fù)執(zhí)行的任務(wù)。
從以下版本開始:
1.3
另請參見:
Timer
構(gòu)造方法摘要
protected?TimerTask()
創(chuàng)建一個新的計時器任務(wù)。
方法摘要
boolean?cancel()
取消此計時器任務(wù)。
abstract void?run()
此計時器任務(wù)要執(zhí)行的操作。
long?scheduledExecutionTime()
返回此任務(wù)最近實際執(zhí)行的安排執(zhí)行時間。
從類java.lang.Object?繼承的方法
clone,?equals,?finalize,?getClass,?hashCode,?notify,?notifyAll,?toString,?wait,?wait,?wait
構(gòu)造方法詳細(xì)信息
TimerTask
protectedTimerTask()
創(chuàng)建一個新的計時器任務(wù)。
方法詳細(xì)信息
run
public abstractvoid run()
此計時器任務(wù)要執(zhí)行的操作。
指定者:
接口Runnable?中的run
另請參見:
Thread.run()
cancel
public booleancancel()
取消此計時器任務(wù)。如果任務(wù)安排為一次執(zhí)行且還未運行,或者尚未安排,則永遠(yuǎn)
不會運行。如果任務(wù)安排為重復(fù)執(zhí)行,則永遠(yuǎn)不會再運行。(如果發(fā)生此調(diào)用時任務(wù)
正在運行,則任務(wù)將運行完,但永遠(yuǎn)不會再運行。)
注意,從重復(fù)的計時器任務(wù)的run?方法中調(diào)用此方法絕對保證計時器任
務(wù)永遠(yuǎn)不會再運行。
此方法可以反復(fù)調(diào)用;第二次和以后的調(diào)用無效。
返回:
如果此任務(wù)安排為一次執(zhí)行且尚未運行,或者此任務(wù)安排為重復(fù)執(zhí)行,則返回true。
如果此任務(wù)安排為一次執(zhí)行且已經(jīng)運行,或者此任務(wù)尚未安排,或者此任務(wù)已經(jīng)取
消,則返回false。(一般來說,如果此方法阻止發(fā)生一個或多個安排執(zhí)行,則返回
true。)
scheduledExecutionTime
public longscheduledExecutionTime()
返回此任務(wù)最近實際執(zhí)行的安排執(zhí)行時間。(如果在任務(wù)執(zhí)行過程中調(diào)用此方法,
則返回值為此任務(wù)執(zhí)行的安排執(zhí)行時間。)
通常從一個任務(wù)的run?方法中調(diào)用此方法,以確定當(dāng)前任務(wù)執(zhí)行是否能
充分及時地保證完成安排活動:
public void run(){
if(System.currentTimeMillis() - scheduledExecutionTime()
>=
MAX_TARDINESS)
return; // Toolate; skip this execution.
// Perform thetask
}
通常,此方法不與固定延遲執(zhí)行的重復(fù)任務(wù)一起使用,因為其安排執(zhí)行時間允許
隨時間浮動,所以毫無意義。
返回:
最近發(fā)生此任務(wù)執(zhí)行安排的時間,采用Date.getTime()?返回的格式。如果任務(wù)已開
始其首次執(zhí)行,則返回值不確定。
另請參見:
Date.getTime()
?
與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的java定时器的使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 帮你理解特征向量的几何意义?
- 下一篇: 对研发人员很有震撼和启发的公式