java的源码为我们提供了一些基础的实现:如Timer类和TimerTask类。
java实现定时任务的方法有一下三种(当然还有很多开源的定时任务框架)。
1)java.util.Timer.
2)ServletContextListener.
3)org.springframework.scheduling.timer.ScheduledTimerTask
1)java.util.Timer
这个方法应该是最常用的,不过这个方法需要手工启动你的任务:
Timer timer=new Timer();
timer.schedule(new ListByDayTimerTask(),10000,86400000);
这里的ListByDayTimerTask类必须extends TimerTask里面的run()方法。
2)ServletContextListener
这个方法在web容器环境比较方便,这样,在web server启动后就可以
自动运行该任务,不需要手工操作。
3)org.springframework.scheduling.timer.ScheduledTimerTask
如果你用spring,那么你不需要写Timer类了,在schedulingContext-timer
.xml中加入下面的内容就可以了:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="timer" class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<ref local="MyTimeTask1"/>
</list>
</property>
</bean>
<bean id="MyTimeTask" class="com.qq.timer.ListByDayTimerTask"/>
<bean id="MyTimeTask1" class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="timerTask">
<ref bean="MyTimeTask"/>
</property>
<property name="delay">
<value>10000</value>
</property>
<property name="period">
<value>86400000</value>
</property>
</bean>
</beans>
下面这个例子是自己结合网上的例子实现的,也就是用第二种方法。怎样利用mvn创建一个web工程,见我的上一篇文章。
1.定时器类
package com.amuse.timer;
import java.util.Timer;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* 类TimerContextListener.java的实现描述:TimerContextListener.java
* <p>
* 实现了ServletContextListener,这样就不用手工启动定时器了,容器启动的时候,定时器就启动了
*
* @author yongchun.chengyc 2012-3-14 下午1:27:00
*/
public class TimerContextListener implements ServletContextListener {
/** 定义一个定时器类 */
private Timer timer = null;
/*
* (non-Javadoc)
* @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)
*/
@Override
public void contextDestroyed(ServletContextEvent event) {
timer.cancel();
event.getServletContext().log("定时器取消");
}
/*
* (non-Javadoc)
* @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
*/
@Override
public void contextInitialized(ServletContextEvent event) {
event.getServletContext().log("已启动定时器");
timer = new Timer(true);
MyTask task = new MyTask(event.getServletContext());
// 每十秒执行一下任务
timer.schedule(task, 0, 10 * 1000);
event.getServletContext().log("已添加任务调度表");
}
}
2.任务类
package com.amuse.timer;
import java.util.TimerTask;
import javax.servlet.ServletContext;
/**
* 类MyTask.java的实现描述:MyTask.java
* <p>
* 继承TimerTask,实现它的run方法
*
* @author yongchun.chengyc 2012-3-14 下午1:36:29
*/
public class MyTask extends TimerTask {
/** 定义一个ServltContext */
private ServletContext context = null;
public MyTask(ServletContext context){
this.context = context;
}
/*
* (non-Javadoc)
* @see java.util.TimerTask#run()
*/
@Override
public void run() {
context.log("开始执行任务");
int i = 0;
while (i++ < 10) {
System.out.println("已完成任务的" + i + "/" + 10);
try {
// 为了看得明白点,这里没完成一次输出睡眠5秒
new Thread().sleep(5 * 1000);
} catch (InterruptedException e) {
context.log(e.getMessage());
}
}
context.log("任务执行结束");
}
}
3.在web.xml文件里配置
<web-app> <display-name>Archetype Created Web Application</display-name> <listener> <listener-class>com.amuse.timer.TimerContextListener</listener-class> </listener> </web-app>
4.运行mvn jetty:run
5.输出结果为:
2012-03-14 14:53:12.685:/timer:INFO: 已启动定时器
2012-03-14 14:53:12.685:/timer:INFO: 已添加任务调度表
2012-03-14 14:53:12.685:/timer:INFO: 开始执行任务
已完成任务的1/10
2012-03-14 14:53:12.722::INFO: Started SelectChannelConnector@0.0.0.0:8080
[INFO] Started Jetty Server
[INFO] Starting scanner at interval of 10 seconds.
已完成任务的2/10
已完成任务的3/10
已完成任务的4/10
已完成任务的5/10
已完成任务的6/10
已完成任务的7/10
已完成任务的8/10
已完成任务的9/10
已完成任务的10/10
2012-03-14 14:54:02.536:/timer:INFO: 任务执行结束
2012-03-14 14:54:02.537:/timer:INFO: 开始执行任务
已完成任务的1/10
已完成任务的2/10
已完成任务的3/10
已完成任务的4/10
已完成任务的5/10
已完成任务的6/10
已完成任务的7/10
已完成任务的8/10
已完成任务的9/10
已完成任务的10/10
2012-03-14 14:54:52.290:/timer:INFO: 任务执行结束
2012-03-14 14:54:52.291:/timer:INFO: 开始执行任务
已完成任务的1/10
已完成任务的2/10
已完成任务的3/10
已完成任务的4/10
已完成任务的5/10
已完成任务的6/10
已完成任务的7/10
已完成任务的8/10
已完成任务的9/10
已完成任务的10/10
2012-03-14 14:55:42.140:/timer:INFO: 任务执行结束
2012-03-14 14:55:42.141:/timer:INFO: 开始执行任务
已完成任务的1/10
已完成任务的2/10
已完成任务的3/10
已完成任务的4/10
已完成任务的5/10
已完成任务的6/10
已完成任务的7/10
已完成任务的8/10
已完成任务的9/10
已完成任务的10/10
2012-03-14 14:56:32.990:/timer:INFO: 任务执行结束
2012-03-14 14:56:32.991:/timer:INFO: 开始执行任务
已完成任务的1/10
已完成任务的2/10
已完成任务的3/10
已完成任务的4/10
已完成任务的5/10
已完成任务的6/10
已完成任务的7/10
已完成任务的8/10
已完成任务的9/10
已完成任务的10/10
2012-03-14 14:57:22.840:/timer:INFO: 任务执行结束
2012-03-14 14:57:22.841:/timer:INFO: 开始执行任务
已完成任务的1/10
已完成任务的2/10
已完成任务的3/10
已完成任务的4/10
已完成任务的5/10
已完成任务的6/10
已完成任务的7/10
已完成任务的8/10
已完成任务的9/10
已完成任务的10/10
2012-03-14 14:58:12.690:/timer:INFO: 任务执行结束
2012-03-14 14:58:12.691:/timer:INFO: 开始执行任务
已完成任务的1/10
已完成任务的2/10
已完成任务的3/10
已完成任务的4/10
已完成任务的5/10
已完成任务的6/10
已完成任务的7/10
已完成任务的8/10
已完成任务的9/10
已完成任务的10/10
Timer--->schedule() ---->Task---run().任务就是像这样的