一、TimerTask
TimerTask代表一个需要多次执行的任务,它实现了Runnable接口,可以在run()方法中定义任务逻辑。
TimerTask相当于Quartz中的StatefulJob(有状态的Job),两种的区别在于,每当执行任务时,Quartz都会创建一个Job实例,而Timer则使用相同的TimerTask实例。所以,如果TimerTask类中拥有状态,那么这些状态对于后面的执行是可见的。
public class SimpleTimerTask extends TimerTask {
//状态,每次任务都使用相同的实例,所以状态是共享的,线程不安全
private int count=0;
//子类覆盖这个run()方法,并定义任务的执行逻辑,每次执行任务时,该方法就会被调用
@Override
public void run() {
System.out.println("Execute task");
//此任务的计划执行时间点,实际执行时间与计划执行时间可能存在不一致
long exeTime=scheduledExecutionTime();
System.out.println("本次任务计划执行时间:"+new Date(exeTime));
//因为count是每个任务共享的,每执行一次任务就会增加
if(++count>5){
//取消任务,在调用该方法后,后续的执行安排将被取消
cancel();
}
}
}
二、Timer
Timer负责制定调度规则并调度TimerTask。
Timer允许在延迟一段时间或在指定时间点后运行一次任务或周期性的运行任务。
每个Timer对象都有一个对应的”背景线程”,Timer构造函数在创建Timer对象的同时将启动一个Timer背景线程。它负责调度并执行Timer中所有的TImerTask。由于所有的TimerTask都在这个线程中执行,所以TimerTask的执行时间比较短,如果一个任务执行占用过多的时间,那么后面的任务会受到影响。
当Timer中所有的TimerTask已经执行完成并且Timer对象没有外部引用时,Timer的任务执行线程才会结束,这需要很长时间。默认情况下,Timer使用非守护线程,可以使用TImer.cancel()方法手动结束Timer。
Timer timer=new Timer();
SimpleTimerTask task=new SimpleTimerTask();
//延迟1秒后,每5秒执行一次任务
timer.schedule(task,1000L,5000L);
//如果不延迟,会在执行一次任务后结束
//timer.cancel();
几个重要方法:
执行一次:
1、schedule(TimerTask task, Date time):在特定的时间点执行一次。
2、schedule(TimerTask task, long delay):延迟指定时间后执行一次任务,单位为毫秒。
固定间隔执行任务(间隔时长为上次任务执行完成时间点到下次任务开始执行的时间点)
1、schedule(TimerTask task, Date firstTime, long period):从指定时间点开始周期性地执行任务,period单位为毫秒,后一次执行将在前一次执行完成后才开始计时。
2、schedule(TimerTask task, long delay, long period):在延迟指定的时间后,周期性地执行任务。
固定频率
1、scheduleAtFixedRate(TimerTask task, Date firstTime,long period):在指定的时间点后,以指定的频率执行任务。假设固定频率是2s,如果第一次执行花费1.5s,则在0.5s后,开始执行第二个任务,以保证固定的执行频率。
2、scheduleAtFixedRate(TimerTask task, long delay, long period):在延迟一段时间后,以指定频率执行任务。
三、Spring对Timer的支持
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.6.SEC03</version>
</dependency>
1、ScheduledTimerTask
对TimerTask提供封装并提供相关的配置
<bean id="timerTask" class="com.smart.service.SimpleTimerTask"/>
<bean id="scheduledTimerTask"class="org.springframework.scheduling.timer.ScheduledTimerTask">
<!--默认是固定间隔-->
<property name="timerTask" ref="timerTask"/>
<property name="delay" value="1000"/>
<!--只希望运行一次,可以设置为0-->
<property name="period" value="1000"/>
<!--设置为固定频率 property name="fixedRate"-->
<!--将实现Runnable接口的类封装成一个任务-->
<!--property name="runnable" ref=""/>
</bean>
2、MethodInvokingTimerTaskFactoryBean将Bean方法封装成一个TimerTask
<bean id="methodTimerTask" class="org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean">
<property name="targetObject" ref="timerTask"/>
<property name="targetMethod" value="run"/>
</bean>
3、TimerFactoryBean
可以将多个ScheduledTimerTask注册到TimerFactoryBean中,TimerFactoryBean将返回一个Timer实例。
<bean id="timer" class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<ref bean="scheduledTimerTask"/>
<ref bean="methodTimerTask"/>
</list>
</property>
</bean>