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 [email protected]: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().任务就是像这样的