转载自: http://www.oschina.net/question/146385_37793?sort=time

下面就Servlet侦听器结合Java定时器来讲述整个实现过程。要运用Servlet侦听器需要实现javax.servlet.ServletContextListener接口,同时实现它的contextInitialized(ServletContextEvent   event)和contextDestroyed(ServletContextEvent   event)两个接口函数。考虑定时器有个建立和销毁的过程,看了前面两个接口函数,就不容置疑的把建立的过程置入contextInitialized,把销毁的过程置入contextDestroyed了。

我把ServletContextListener的实现类取名为ContextListener,在其内添加一个定时器,示例代码如下所示(为考虑篇幅,仅提供部分代码供读者参考):

1
2
3
4
5
6
7
8
9
10
11
private java.util.Timer timer = null;   
public void contextInitialized(ServletContextEvent event){   
          timer = new java.util.Timer(true);   
          event.getServletContext().log("定时器已启动");                   
          timer.schedule(new MyTask(event.getServletContext()),0,60*60*1000);   
          event.getServletContext().log("已经添加任务调度表");   
}   
public void contextDestroyed(ServletContextEvent event){   
          timer.cancel();   
          event.getServletContext().log("定时器销毁");   
}

以上代码中,   timer.schedule(new MyTask(event.getServletContext()), 0, 60*60*1000) 这一行为定时器调度语句,其中MyTask是自定义需要被调度的执行任务(在我的财政数据中心项目中就是报表计算引擎入口),从java.util.TimerTask继承,下面会重点讲述,第三个参数表示每小时(即60*60*1000毫秒)被触发一次,中间参数0表示无延迟。其它代码相当简单,不再详细说明。

下面介绍MyTask的实现,上面的代码中看到了在构造MyTask时,传入了javax.servlet.ServletContext类型参数,是为记录Servlet日志方便而传入,因此需要重载MyTask的构造函数(其父类java.util.TimerTask原构造函数是没有参数的)。在timer.schedule()的调度中,设置了每小时调度一次,因此如果想实现调度任务每24小时被执行一次,还需要判断一下时钟点,以常量C_SCHEDULE_HOUR表示(晚上12点,也即0点)。同时为防止24小时执行下来,任务还未执行完(当然,一般任务是没有这么长的),避免第二次又被调度以引起执行冲突,设置了当前是否正在执行的状态标志isRunning。示例代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
private static final int C_SCHEDULE_HOUR = 0;   
 private static boolean isRunning = false;   
 private ServletContext context = null;
    
 public MyTask(ServletContext context)   {   
         this.context = context;   
 
 public void run(){   
    Calendar cal = Calendar.getInstance();                   
    if(!isRunning){                         
        if(C_SCHEDULE_HOUR == cal.get(Calendar.HOUR_OF_DAY)){                           
             isRunning   =   true;                                   
             context.log("开始执行指定任务");   
                              
            //TODO   添加自定义的详细任务,以下只是示例   
            int i = 0;   
            while(i++ < 10){   
                 context.log("已完成任务的"   +   i   +   "/"   +   10);   
            }   
            isRunning   =   false;   
            context.log("指定任务执行结束");                                 
        }                           
    } else {   
        context.log("上一次任务执行还未结束");   
    }   
}

上面代码中“//TODO……”之下四行是真正被调度执行的演示代码(在我的财政数据中心项目中就是报表计算过程),您可以换成自己希望执行的语句。

到这儿,ServletContextListener和MyTask的代码都已完整了。最后一步就是把ServletContextListener部署到您的Web工程中去,在您工程的web.xml配置文件中加入如下三行:

1
2
3
<listener
    <listener-class>com.test.ContextListener</listener-class
</listener>

当然,上面的com.test得换成您自己的包名了。保存web.xml文件后,把工程打包部署到Tomcat中即可。任务会在每晚12点至凌晨1点之间被执行,上面的代码会在Tomcat的日志文件中记录如下:

2003-12-05   0:21:39   开始执行指定任务   
  2003-12-05   0:21:39   已完成任务的1/10   
          ……   
  2003-12-05   0:21:39   已完成任务的10/10   
  2003-12-05   0:21:39   指定任务执行结束

如何在Web工程中实现任务计划调度的更多相关文章

  1. web工程中URL地址的推荐写法

    三.web工程中URL地址的推荐写法 使用c标签<c:url value="" /> 会自动添加项目名 -> value中的值 前面要加 “/” 在JavaWeb ...

  2. web工程中URL地址的写法

    在开发中我们不可避免的要碰到许多需要写URL地址的情况,这常常让我们感到头疼.下面笔者推荐一种简单的做法.URL地址分为绝对路径和相对路径两种.相对路径又分为相对资源路径和相对根路径.显然绝对路径在开 ...

  3. [译]如何在Web开发中使用Python

    [译]如何在Web开发中使用Python 原文:HOWTO Use Python in the Web 摘要 这篇文档展示了Python如何融入到web中.它介绍了几种Python结合web服务器的方 ...

  4. Spring 如何在 WEB 应用中使用

    1. Spring 如何在 WEB 应用中使用 ? 1). 需要额外加入的 jar 包: spring-web-4.0.0.RELEASE.jar spring-webmvc-4.0.0.RELEAS ...

  5. web工程中的各种路径(eclipse开发)

    目前遇到的 web 工程中要写url和路径的文件有 webContent中.jsp/.html :action src中的servlet类 : 映射地址.重定向.请求转发.访问资源文件(webCont ...

  6. 读取web工程中.properties资源文件的模板代码

    读取web工程中.properties资源文件的模板代码 // 读取web工程中.properties资源文件的模板代码 private void test2() throws IOException ...

  7. 在Web工程中引入Jquery插件报错解决方案

    在学习Jquery插件的时候,遇到一个问题就是新建web工程后在WebRoot下引入Jquery插件的时候报错,不知道为什么好纠结,但是项目能正常运行,后来找到解决方案,在这里给大家分享一下. 解决方 ...

  8. 设置java web工程中默认访问首页的几种方式

    1.demo中最常见的方式是在工程下的web.xml中设置(有时候根据业务可能需要设置action,在action中处理逻辑加载跳转什么的,比较少): <welcome-file-list> ...

  9. 关于eclipse中MAVEN WEB工程中编译问题

    这几天是被java的环境搞疯了,我先是搭了一个spring+springmvc+mybatis的工程,在家里跑了一下,没有问题,把工程带到公司里用,却一直不能使用. 按常理来说,只要工程发生一点变化, ...

随机推荐

  1. java Byte源码分析

    源码: public static int toUnsignedInt(byte x) { return ((int) x) & 0xff; } 原理: -128(byte) 原码:10000 ...

  2. js赋值后 改变现有数据会修改原来的数据

    看代码: let obj1 = { name: '张三', age: , sex: '男' } let obj2 = obj1 console.log('obj2:', obj2) obj2.age ...

  3. Django【第24篇】:JS实现的ajax和同源策略

    JS实现的ajax和同源策略 一.回顾jQuery实现的ajax 首先说一下ajax的优缺点 优点: AJAX使用Javascript技术向服务器发送异步请求: AJAX无须刷新整个页面: 因为服务器 ...

  4. CCF201412-2 Z字形扫描 java(100分)

    试题编号: 201412-2 试题名称: Z字形扫描 时间限制: 2.0s 内存限制: 256.0MB 问题描述: 问题描述 在图像编码的算法中,需要将一个给定的方形矩阵进行Z字形扫描(Zigzag ...

  5. JDK7

    https://docs.oracle.com/javase/7/docs/index.html

  6. 【bzoj2002】弹飞绵羊

    题目 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数k ...

  7. Rosetta Stone 不在C盘安装步骤

    本文出自:http://www.cnblogs.com/2186009311CFF/p/7500637.html Rosetta Stone默认安装在C盘的,很不好,故找到次解决方案: 总体就是移动文 ...

  8. luogu 3488 [POI2009]LYZ-Ice Skates 线段树 + 思维

    Code: #include <bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin), ...

  9. codevs 3137-3139 栈练习 x

    3中 换行需谨慎!!!一定要注意换行!!! 3137 栈练习1  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold     题目描述 Description 给定一 ...

  10. leetcode-mid-Linked list- 105. Construct Binary Tree from Preorder and Inorder Traversal

    mycode   43.86% # Definition for a binary tree node. # class TreeNode(object): # def __init__(self, ...