JDK Timer實(shí)例
首先創(chuàng)建一個(gè)任務(wù),并在運(yùn)行10次以后退出運(yùn)行,代碼如下:
package com.baobaotao.basic.timer;
import java.util.Date;
import java.util.TimerTask;
public class SimpleTimerTaskextends TimerTask{
private int count = 0;
public void run() {
System.out.println("execute task.");
Date exeTime = (new Date(scheduledExecutionTime()));①獲取本次安排執(zhí)行的時(shí)間點(diǎn)
System.out.println("本次任務(wù)安排執(zhí)行時(shí)間點(diǎn)為:"+exeTime);
if(++count > 10)② 在任務(wù)運(yùn)行10次后主動退出運(yùn)行
}
}
通過擴(kuò)展TimerTask并實(shí)現(xiàn)run()抽象方法定義一個(gè)任務(wù)。在JDK Timer中沒有指定運(yùn)行特定次數(shù)任務(wù)的方法。你可以在任務(wù)的run()方法中通過自定義代碼實(shí)現(xiàn)。
下面通過Timer以固定延遲時(shí)間的方式每5秒執(zhí)行一次任務(wù):
package com.baobaotao.basic.timer;
import java.util.Timer;
import java.util.TimerTask;
public class TimerRunner {
public static void main(String[] args) {
Timer timer = new Timer();
TimerTask task = new SimpleTimerTask();
timer.schedule(task,1000L,5000L); ①在延遲1秒鐘后,每5秒鐘運(yùn)行一次任務(wù)
}
}
運(yùn)行以上代碼,將輸出以下信息:
execute task.
本次任務(wù)安排執(zhí)行時(shí)間點(diǎn)為:Thu Mar 15 18:39:37 CST 2007
execute task.
本次任務(wù)安排執(zhí)行時(shí)間點(diǎn)為:Thu Mar 15 18:39:42 CST 2007
execute task.
本次任務(wù)安排執(zhí)行時(shí)間點(diǎn)為:Thu Mar 15 18:39:47 CST 2007
Spring對JDK Timer的支持
Spring在org.springframework.scheduling.timer中提供了幾個(gè)JDK Timer的支持類,主要在以下三方面對JDK Timer提供了支持:
1) ScheduledTimerTask,它對TimerTask提供封裝并或配置調(diào)度信息;
2)通過MethodInvokingTimerTaskFactoryBean類可以將一個(gè)Bean的方法封裝為TimerTask;
3)通過TimerFactoryBean可以更方便地配置Timer,此外讓Timer的生命周期和Spring容器的生命周期相關(guān),在初始化TimerFactoryBean后,啟動Timer,在Spring容器關(guān)閉前取消Timer。
使用ScheduledTimerTask
JDK Timer標(biāo)準(zhǔn)的API要求我們使用Timer方法進(jìn)行任務(wù)調(diào)度時(shí)才指定調(diào)度的規(guī)則,這種方式不太適合進(jìn)行Bean的配置,因此Spring提供了ScheduledTimerTask,通過屬性指定任務(wù)和調(diào)度規(guī)則,請看下面的代碼:
<bean id="timerTask"class="com.baobaotao.basic.timer.SimpleTimerTask" />
<bean id="scheduledTask"class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="timerTask" ref="timerTask" />①指定調(diào)度任務(wù)
<property name="delay" value="1000" />②延遲時(shí)間,單位為毫秒
<property name="period" value="1000" />③周期時(shí)間,單位為毫秒
</bean>
如果只希望運(yùn)行一次任務(wù),將period設(shè)置為0或負(fù)值。默認(rèn)情況下,采用固定時(shí)間間隔的調(diào)度方式,可以通過fixedRate屬性,以固定頻率的方式運(yùn)行任務(wù)。SimpleTimerTask還可以將實(shí)現(xiàn)了Runnable接口的類封裝成一個(gè)任務(wù),你可以通過runnable屬性進(jìn)行設(shè)置。
MethodInvokingTimerTaskFactoryBean
類似于Quartz的MethodInvokingJobDetailFactoryBean,Spring也為JDK Timer提供了一個(gè)方便類用以將Bean方法封裝成一個(gè)TimerTask:
<bean id="myService" class="com.baobaotao.service.MyService" />
<bean id="timerTask1"① 將返回一個(gè)TimerTask實(shí)例
class="org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean">
<property name="targetObject" ref="myService" />② 業(yè)務(wù)Bean
<property name="targetMethod" value="doJob" />③ 業(yè)務(wù)方法
</bean>
TimerFactoryBean
類似于Quartz的SchedulerFactoryBean,Spring為Timer提供了TimerFactoryBean類。你可以將多個(gè)ScheduledTimerTask注冊到TimerFactoryBean中,TimerFactoryBean將返回一個(gè)Timer實(shí)例。在TimerFactoryBean初始化完成后,對應(yīng)的Timer啟動,在Spring 容器關(guān)閉之前,TimerFactoryBean將取消Timer。請看下面的配置代碼:
<bean id="timer"class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<ref bean="scheduledTask" />
</list>
</property>
</bean>
scheduledTimerTasks屬性的類型為ScheduledTimerTask[],可以注入多個(gè)ScheduledTimerTask。此外TimerFactoryBean還擁有一個(gè)daemon屬性,指定生成Timer的背景線程是否為后臺線程。
小結(jié)
JDK Timer可以滿足一些簡單的任務(wù)調(diào)度需求,好處就是你不必引用JDK之外的第三方類庫,學(xué)習(xí)也很簡單。
但你必須保證你的任務(wù)是短小型的任務(wù),任務(wù)應(yīng)該很快就能執(zhí)行完成,否則將產(chǎn)生“時(shí)間漂移”的問題。此外,使用JDK Timer的任務(wù)對執(zhí)行時(shí)間點(diǎn)應(yīng)該沒有嚴(yán)格的要求,因?yàn)镴DK Timer只能做到近似的時(shí)間安排。
|