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對象要在后臺啟動一個線程。這種性質在一些托管的環境下不推
?
薦使用,比如在應用服務器中。因為這些線程不在容器的控制范圍之內了。
?
具體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()
轉載于:https://www.cnblogs.com/alter888/p/8986697.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的java定时器的使用(Timer)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 索尼9300e为什么很重
- 下一篇: python安装Crypto:Nomod