定时器类Timer在java
util包中
使用时
先实例化
然后使用实例的schedule(TimerTask task
long delay)方法
设定指定的任务task在指定的延迟delay后执行
定时器任务类TimerTask是抽象类
继承并重写其run()方法
可实现具体任务
schedule(TimerTask task Date time)设定指定任务task在指定时间time执行
cancel()方法结束这个定时器
schedule(TimerTask task long delay long period)方法设定指定任务task在指定延迟delay后进行固定延迟peroid的执行
scheduleAtFixedRate(TimerTask task long delay long period)方法设定指定任务task在指定延迟delay后进行固定频率peroid的执行
要实现一个定时任务运用java中的Timer和TimerTask类可以非常容易实现实时调用处理函数这两个类使用起来非常方便可以完成我们对定时器的绝大多数需要
看个简单的例子
import javaioIOException;
import javautilTimer;
public class TimerTest {
public static void main(String[] args){
Timer timer = new Timer()
timerschedule(new MyTask() )//在秒后执行此任务每次间隔秒如果传递一个Data参数就可以在某个固定的时间执行这个任务
while(true){//这个是用来停止此任务的否则就一直循环执行此任务了
try {
int ch = Systeminread()
if(chc==){
timercancel()//使用这个方法退出任务
}
} catch (IOException e) {
// TODO Autogenerated catch block
eprintStackTrace()
}
}
}
static class MyTask extends javautilTimerTask{
@Override
public void run() {
// TODO Autogenerated method stub
Systemoutprintln(________)
}
}
}
Servlet侦听器结合Java定时器实现任务计划调度[转]
好多朋友用过Windows的任务计划也有不少程序迷自己曾写过时钟报警系统自动关机等趣味程序可却很少有朋友在Web工程中实现过类似功能今天有空把笔者先前曾在Tomcat上实现的类似功能搬出来与大家共享
早在几年前我公司跟某市财政局合作项目开发为加强财政局对所属单位财务状况的有效监管开发实施了财政局数据中心项目此项目采用B/S加C/S混合结构模式财政局Web服务器上架设数据同步接收装置由市属单位每天下班前把财务信息通过HTTP协议上传至财政局中心服务器与Web服务器上的接收装置对接财政局内部各部门需要查阅大量财务信息获取完备的市属单位当前财务状况信息各部门按职能划分需要准确的获取各部门各自所关注的汇总信息以财政报表的形式提供
因财政数据量大实时计算财政报表速度较慢当初就考虑用报表缓存来减轻服务器的负担但用缓存需要一个合理的缓存更新机制考虑到各市属单位每天下班前才把财务数据上传财政局每天所查看到的财务信息其实并不包括当天(除非有某位领导等到所属单位全部上传完之后才来查看信息应该已经下班了)所以要是能实现任务计划调度在每晚深夜把当天及历史财务信息汇总更新缓存速度瓶颈不就解决了吗
当时由于系统核心是基于Web部署的报表计算引擎也相应的部署在Tomcat容器上因此如果想要借用Windows的任务计划来实现定时计算就需要额外编写普通桌面应用程序接口稍显复杂于是就琢磨着想在Web上实现经过查阅较多相关资料发现Java定时器(javautilTimer)有定时触发计划任务的功能通过配置定时器的间隔时间在某一间隔时间段之后会自动有规律的调用预先所安排的计划任务(javautilTimerTask)另外由于我们希望当Web工程启动时定时器能自动开始计时在整个Web工程的生命期里定时器能在每晚深夜触发一次报表计算引擎因此定时器的存放位置也值得考查不能简单的存在于单个Servlet或JavaBean中必须能让定时器宿主的存活期为整个Web工程生命期在工程启动时能自动加载运行结合这两点跟Servlet上下文有关的侦听器就最合适不过了通过在工程的配置文件中加以合理配置会在工程启动时自动运行并在整个工程生命期中处于监听状态
下面就Servlet侦听器结合Java定时器来讲述整个实现过程要运用Servlet侦听器需要实现javaxservletServletContextListener接口同时实现它的contextInitialized(ServletContextEvent event)和contextDestroyed(ServletContextEvent event)两个接口函数考虑定时器有个建立和销毁的过程看了前面两个接口函数就不容置疑的把建立的过程置入contextInitialized把销毁的过程置入contextDestroyed了
我把ServletContextListener的实现类取名为ContextListener在其内添加一个定时器示例代码如下所示(为考虑篇幅仅提供部分代码供读者参考)
private javautilTimer timer = null;
public void contextInitialized(ServletContextEvent event) {
timer = new javautilTimer(true)
eventgetServletContext()log(定时器已启动)
timerschedule(new MyTask(eventgetServletContext()) **)
eventgetServletContext()log(已经添加任务调度表)
}
public void contextDestroyed(ServletContextEvent event) {
timercancel()
eventgetServletContext()log(定时器销毁)
}
以上代码中 timerschedule(new MyTask(eventgetServletContext()) **)这一行为定时器调度语句其中MyTask是自定义需要被调度的执行任务(在我的财政数据中心项目中就是报表计算引擎入口)从javautilTimerTask继承下面会重点讲述第三个参数表示每小时(即**毫秒)被触发一次中间参数表示无延迟其它代码相当简单不再详细说明
下面介绍MyTask的实现上面的代码中看到了在构造MyTask时传入了javaxservletServletContext类型参数是为记录Servlet日志方便而传入因此需要重载MyTask的构造函数(其父类javautilTimerTask原构造函数是没有参数的)在timerschedule()的调度中设置了每小时调度一次因此如果想实现调度任务每小时被执行一次还需要判断一下时钟点以常量C_SCHEDULE_HOUR表示(晚上点也即点)同时为防止小时执行下来任务还未执行完(当然一般任务是没有这么长的)避免第二次又被调度以引起执行沖突设置了当前是否正在执行的状态标志isRunning示例代码如下所示
private static final int C_SCHEDULE_HOUR = ;
private static boolean isRunning = false;
private ServletContext context = null;
public MyTask(ServletContext context) {
ntext = context;
}
public void run() {
Calendar cal = CalendargetInstance()
if (!isRunning) {
if (C_SCHEDULE_HOUR == calget(CalendarHOUR_OF_DAY)) {
isRunning = true;
contextlog(开始执行指定任务)
//TODO 添加自定义的详细任务以下只是示例
int i = ;
while (i++ < ) {
contextlog(已完成任务的 + i + / + )
}
isRunning = false;
contextlog(指定任务执行结束)
}
} else {
contextlog(上一次任务执行还未结束)
}
}
上面代码中//TODO……之下四行是真正被调度执行的演示代码(在我的财政数据中心项目中就是报表计算过程)您可以换成自己希望执行的语句
到这儿ServletContextListener和MyTask的代码都已完整了最后一步就是把ServletContextListener部署到您的Web工程中去在您工程的webxml配置文件中加入如下三行
comtestContextListener
当然上面的comtest得换成您自己的包名了保存webxml文件后把工程打包部署到Tomcat中即可任务会在每晚点至凌晨点之间被执行上面的代码会在Tomcat的日志文件中记录如下
:: 开始执行指定任务
:: 已完成任务的/
……
:: 已完成任务的/
:: 指定任务执行结束