java每五分钟执行_java关于Timer schedule执行定时任务 1、在应用开发中,经常需要一些周期性的操作,比如每5分钟执行某一操作等...
1、在應(yīng)用開(kāi)發(fā)中,經(jīng)常需要一些周期性的操作,比如每5分鐘執(zhí)行某一操作等。對(duì)于這樣的操作最方便、高效的實(shí)現(xiàn)方式就是使用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);
第一個(gè)參數(shù)是要操作的方法,第二個(gè)參數(shù)是要設(shè)定延遲的時(shí)間,第三個(gè)參數(shù)是周期的設(shè)定,每隔多長(zhǎng)時(shí)間執(zhí)行該操作。
使用這幾行代碼之后,Timer本身會(huì)每隔5分鐘調(diào)用一遍server.checkNewMail()方法,不需要自己?jiǎn)?dòng)線程。Timer本身也是多線程同步的,多個(gè)線程可以共用一個(gè)Timer,不需要外部的同步代碼。
2、
(1)Timer.schedule(TimerTask task,Date time)安排在制定的時(shí)間執(zhí)行指定的任務(wù)。
(2)Timer.schedule(TimerTask task,Date firstTime ,long period)安排指定的任務(wù)在指定的時(shí)間開(kāi)始進(jìn)行重復(fù)的固定延遲執(zhí)行.
(3)Timer.schedule(TimerTask task,long delay)安排在指定延遲后執(zhí)行指定的任務(wù).
(4)Timer.schedule(TimerTask task,long delay,long period)安排指定的任務(wù)從指定的延遲后開(kāi)始進(jìn)行重復(fù)的固定延遲執(zhí)行.
(5)Timer.scheduleAtFixedRate(TimerTask task,Date firstTime,long period)安排指定的任務(wù)在指定的時(shí)間開(kāi)始進(jìn)行重復(fù)的固定速率執(zhí)行.
(6)Timer.scheduleAtFixedRate(TimerTask task,long delay,long period)安排指定的任務(wù)在指定的延遲后開(kāi)始進(jìn)行重復(fù)的固定速率執(zhí)行.
以下內(nèi)容根據(jù)?The?JavaTM?Tutorial?和相關(guān)API?doc翻譯整理,以供日后參考:
1.概覽
Timer是一種定時(shí)器工具,用來(lái)在一個(gè)后臺(tái)線程計(jì)劃執(zhí)行指定任務(wù)。它可以計(jì)劃執(zhí)行一個(gè)任務(wù)一次或反復(fù)多次。
TimerTask一個(gè)抽象類,它的子類代表一個(gè)可以被Timer計(jì)劃的任務(wù)。
簡(jiǎn)單的一個(gè)例程:
importjava.util.Timer;
importjava.util.TimerTask;
/***?Simple?demo?that?uses?java.util.Timer?to?schedule?a?task?to?execute
*?once?5?seconds?have?passed.
*/
publicclassReminder?{
????Timer?timer;
????publicReminder(intseconds)?{
????????timer?=newTimer();
????????timer.schedule(newRemindTask(),?seconds*1000);
????}
????classRemindTask?extendsTimerTask?{
????????publicvoidrun()?{
????????????System.out.println("Time's?up!");
????????????timer.cancel();?//Terminate?the?timer?thread}????}
????publicstaticvoidmain(String?args[])?{
????????System.out.println("About?to?schedule?task.");
????????newReminder(5);
????????System.out.println("Task?scheduled.");
????}}
運(yùn)行這個(gè)小例子,你會(huì)首先看到:
About?to?schedule?task.
5秒鐘之后你會(huì)看到:
Time's?up!
這個(gè)小例子可以說(shuō)明一些用Timer線程實(shí)現(xiàn)和計(jì)劃執(zhí)行一個(gè)任務(wù)的基礎(chǔ)步驟:
實(shí)現(xiàn)自定義的TimerTask的子類,run方法包含要執(zhí)行的任務(wù)代碼,在這個(gè)例子里,這個(gè)子類就是RemindTask。
實(shí)例化Timer類,創(chuàng)建計(jì)時(shí)器后臺(tái)線程。
實(shí)例化任務(wù)對(duì)象?(new?RemindTask()).
制定執(zhí)行計(jì)劃。這里用schedule方法,第一個(gè)參數(shù)是TimerTask對(duì)象,第二個(gè)參數(shù)表示開(kāi)始執(zhí)行前的延時(shí)時(shí)間(單位是milliseconds,這里定義了5000)。還有一種方法可以指定任務(wù)的執(zhí)行時(shí)間,如下例,指定任務(wù)在11:01?p.m.執(zhí)行:
//Get?the?Date?corresponding?to?11:01:00?pm?today.
Calendar?calendar?=?Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY,?23);
calendar.set(Calendar.MINUTE,?1);
calendar.set(Calendar.SECOND,?0);
Date?time?=?calendar.getTime();
timer?=?new?Timer();
timer.schedule(new?RemindTask(),?time);
2.終止Timer線程
默認(rèn)情況下,只要一個(gè)程序的timer線程在運(yùn)行,那么這個(gè)程序就會(huì)保持運(yùn)行。當(dāng)然,你可以通過(guò)以下四種方法終止一個(gè)timer線程:
調(diào)用timer的cancle方法。你可以從程序的任何地方調(diào)用此方法,甚至在一個(gè)timer?task的run方法里。
讓timer線程成為一個(gè)daemon線程(可以在創(chuàng)建timer時(shí)使用new?Timer(true)達(dá)到這個(gè)目地),這樣當(dāng)程序只有daemon線程的時(shí)候,它就會(huì)自動(dòng)終止運(yùn)行。
當(dāng)timer相關(guān)的所有task執(zhí)行完畢以后,刪除所有此timer對(duì)象的引用(置成null),這樣timer線程也會(huì)終止。
調(diào)用System.exit方法,使整個(gè)程序(所有線程)終止。
Reminder
的例子使用了第一種方式。在這里不能使用第二種方式,因?yàn)檫@里需要程序保持運(yùn)行直到timer的任務(wù)執(zhí)行完成,如果設(shè)成daemon,那么當(dāng)main線程
結(jié)束的時(shí)候,程序只剩下timer這個(gè)daemon線程,于是程序不會(huì)等timer線程執(zhí)行task就終止了。
有些時(shí)候,程序的終止與
否
并不只與timer線程有關(guān)。舉個(gè)例子,如果我們使用AWT來(lái)beep,那么AWT會(huì)自動(dòng)創(chuàng)建一個(gè)非daemon線程來(lái)保持程序的運(yùn)行。下面的代碼我們對(duì)
Reminder做了修改,加入了beeping功能,于是我們需要加入System.exit的調(diào)用來(lái)終止程序。
importjava.util.Timer;
importjava.util.TimerTask;
importjava.awt.Toolkit;
/***?Simple?demo?that?uses?java.util.Timer?to?schedule?a?task?to?execute
*?once?5?seconds?have?passed.
*/
publicclassReminderBeep?{
????Toolkit?toolkit;
????Timer?timer;
????publicReminderBeep(intseconds)?{
????????toolkit?=Toolkit.getDefaultToolkit();
????????timer?=newTimer();
????????timer.schedule(newRemindTask(),?seconds*1000);
????}
????classRemindTask?extendsTimerTask?{
????????publicvoidrun()?{
????????????System.out.println("Time's?up!");
????toolkit.beep();
????//timer.cancel();?//Not?necessary?because?we?call?System.exitSystem.exit(0);???//Stops?the?AWT?thread?(and?everything?else)}????}
????publicstaticvoidmain(String?args[])?{
System.out.println("About?to?schedule?task.");
????????newReminderBeep(5);
System.out.println("Task?scheduled.");
????}}
3.反復(fù)執(zhí)行一個(gè)任務(wù)
先看一個(gè)例子:
publicclassAnnoyingBeep?{
????Toolkit?toolkit;
????Timer?timer;
????publicAnnoyingBeep()?{
????????toolkit?=Toolkit.getDefaultToolkit();
????????timer?=newTimer();
????????timer.schedule(newRemindTask(),
???????????????0,????????//initial?delay1*1000);??//subsequent?rate}
????classRemindTask?extendsTimerTask?{
????????intnumWarningBeeps?=3;
????????publicvoidrun()?{
????????????if(numWarningBeeps?>0)?{
????????????????toolkit.beep();
????????????????System.out.println("Beep!");
????????????????numWarningBeeps--;
????????????}else{
????????????????toolkit.beep();?
????????????????System.out.println("Time's?up!");
????????????????//timer.cancel();?//Not?necessary?because?we?call?System.exitSystem.exit(0);???//Stops?the?AWT?thread?(and?everything?else)}????????}????}????...
}
執(zhí)行,你會(huì)看到如下輸出:
Task?scheduled.
Beep!
Beep!??????//one?second?after?the?first?beep
Beep!??????//one?second?after?the?second?beep
Time's?up!?//one?second?after?the?third?beep
這里使用了三個(gè)參數(shù)的schedule方法用來(lái)指定task每隔一秒執(zhí)行一次。如下所列為所有Timer類用來(lái)制定計(jì)劃反復(fù)執(zhí)行task的方法?:
schedule(TimerTask?task,?long?delay,?long?period)
schedule(TimerTask?task,?Date?time,?long?period)
scheduleAtFixedRate(TimerTask?task,?long?delay,?long?period)
scheduleAtFixedRate(TimerTask?task,?Date?firstTime,?long?period)
當(dāng)
計(jì)劃反復(fù)執(zhí)行的任務(wù)時(shí),如果你注重任務(wù)執(zhí)行的平滑度,那么請(qǐng)使用schedule方法,如果你在乎的是任務(wù)的執(zhí)行頻度那么使用
scheduleAtFixedRate方法。?例如,這里使用了schedule方法,這就意味著所有beep之間的時(shí)間間隔至少為1秒,也就是說(shuō),如
果有一個(gè)beap因?yàn)槟撤N原因遲到了(未按計(jì)劃執(zhí)行),那么余下的所有beep都要延時(shí)執(zhí)行。如果我們想讓這個(gè)程序正好在3秒以后終止,無(wú)論哪一個(gè)
beep因?yàn)槭裁丛虮谎訒r(shí),那么我們需要使用scheduleAtFixedRate方法,這樣當(dāng)?shù)谝粋€(gè)beep遲到時(shí),那么后面的beep就會(huì)以最快
的速度緊密執(zhí)行(最大限度的壓縮間隔時(shí)間)。
4.進(jìn)一步分析schedule和scheduleAtFixedRate
(1)
2個(gè)參數(shù)的schedule在制定任務(wù)計(jì)劃時(shí),?如果指定的計(jì)劃執(zhí)行時(shí)間scheduledExecutionTime<=
systemCurrentTime,則task會(huì)被立即執(zhí)行。scheduledExecutionTime不會(huì)因?yàn)槟骋粋€(gè)task的過(guò)度執(zhí)行而改變。
(2)
3個(gè)參數(shù)的schedule在制定反復(fù)執(zhí)行一個(gè)task的計(jì)劃時(shí),每一次執(zhí)行這個(gè)task的計(jì)劃執(zhí)行時(shí)間隨著前一次的實(shí)際執(zhí)行時(shí)間而變,也就是
scheduledExecutionTime(第n+1次)=realExecutionTime(第n次)+periodTime。也就是說(shuō)如果第n
次執(zhí)行task時(shí),由于某種原因這次執(zhí)行時(shí)間過(guò)長(zhǎng),執(zhí)行完后的systemCurrentTime>=
scheduledExecutionTime(第n+1次),則此時(shí)不做時(shí)隔等待,立即執(zhí)行第n+1次task,而接下來(lái)的第n+2次task的
scheduledExecutionTime(第n+2次)就隨著變成了realExecutionTime(第n+1次)+periodTime。說(shuō)
白了,這個(gè)方法更注重保持間隔時(shí)間的穩(wěn)定。
(3)3個(gè)參數(shù)的scheduleAtFixedRate在制定反復(fù)執(zhí)行一個(gè)task的計(jì)劃時(shí),每一
次
執(zhí)行這個(gè)task的計(jì)劃執(zhí)行時(shí)間在最初就被定下來(lái)了,也就是scheduledExecutionTime(第n次)=firstExecuteTime
+n*periodTime;如果第n次執(zhí)行task時(shí),由于某種原因這次執(zhí)行時(shí)間過(guò)長(zhǎng),執(zhí)行完后的systemCurrentTime>=
scheduledExecutionTime(第n+1次),則此時(shí)不做period間隔等待,立即執(zhí)行第n+1次task,而接下來(lái)的第n+2次的
task的scheduledExecutionTime(第n+2次)依然還是firstExecuteTime+(n+2)*periodTime這
在第一次執(zhí)行task就定下來(lái)了。說(shuō)白了,這個(gè)方法更注重保持執(zhí)行頻率的穩(wěn)定。
總結(jié)
以上是生活随笔為你收集整理的java每五分钟执行_java关于Timer schedule执行定时任务 1、在应用开发中,经常需要一些周期性的操作,比如每5分钟执行某一操作等...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 什么是面向对象编程?终于懂了
- 下一篇: 最新干货下载 | 《5G应用创新发展白皮