Java定时器(java.util.Timer)有定时触发计划任务的功能,通过配置定时器的间隔时间,在某一间隔时间段之后会自动有规律的调用预先所 安排的计划任务(java.util.TimerTask)。另外,由于我们希望当Web工程启动时,定时器能自动开始计时,在整个Web工程的生命期 里,定时器能在每晚深夜触发一次报表计算引擎。因此定时器的存放位置也值得考查,不能简单的存在于单个Servlet或JavaBean中,必须能让定时 器宿主的存活期为整个Web工程生命期,在工程启动时能自动加载运行。结合这两点,跟Servlet上下文有关的侦听器就最合适不过了,通过在工程的配置 文件中加以合理配置,会在工程启动时自动运行,并在整个工程生命期中处于监听状态。

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

java 代码 1
  1. package com.derek.servlet;
  2. import javax.servlet.*;
  3. import javax.servlet.http.*;
  4. import com.derek.pub.TimerManager;
  5. /**
  6. * 启动定时器的监听器
  7. * @author derek
  8. * @version 1.0
  9. */
  10. public class TimerListener extends HttpServlet implements
  11. ServletContextListener {
  12. private TimerManager tm = null;
  13. //Notification that the web module is ready to process requests
  14. public void contextInitialized(ServletContextEvent sce) {
  15. int day,hour,min,sec;
  16. day = 26; hour = 16; min = 42; sec = 0;
  17. tm = new TimerManager(day,hour,min,sec);
  18. }
  19. //Notification that the servlet context is about to be shut down
  20. public void contextDestroyed(ServletContextEvent sce) {
  21. tm.destoryTimer();
  22. }
  23. }
java 代码 2
  1. package com.derek.pub;
  2. import java.util.Timer;
  3. import java.util.Date;
  4. import java.util.Calendar;
  5. /**
  6. * 定时器
  7. * @author derek
  8. * @version 1.0
  9. */
  10. public class TimerManager {
  11. Timer t = null;
  12. public TimerManager(int day,int hour,int min,int sec) {
  13. time(day,hour,min,sec);
  14. }
  15. public void time(int day,int hour,int min,int sec){
  16. Calendar c = Calendar.getInstance();
  17. c.set(Calendar.DAY_OF_MONTH,day);
  18. c.set(Calendar.HOUR_OF_DAY,hour);
  19. c.set(Calendar.MINUTE,min);
  20. c.set(Calendar.SECOND,sec);
  21. Date date = c.getTime();
  22. System.out.println(c.getTime());
  23. t= new Timer();
  24. MyTask mt = new MyTask();
  25. t.schedule(mt,date);
  26. }
  27. public void destoryTimer(){
  28. t.cancel();
  29. }
  30. }
java 代码 3
  1. package com.derek.pub;
  2. import java.util.TimerTask;
  3. /**
  4. * 计划任务代码
  5. * @author derek
  6. * @version 1.0
  7. */
  8. public class MyTask extends TimerTask{
  9. public MyTask() {
  10. }
  11. /**
  12. * 任务块
  13. */
  14. public void run() {
  15. System.out.println("定时器RUN");
  16. }
  17. }
好多朋友用过Windows的任务计划,也有不少程序迷自己曾写过时钟报警、系统自动关机等趣味程序,可却很少有朋友在Web工程中实现过类似功能。今天有空把笔者先前曾在Tomcat上实现的类似功能,搬出来与大家共享。
早在几年前,我公司跟某市财政局合作项目开发,为加强财政局对所属单位财务状况的有效监管,开发、实施了财政局数据中心项目。此项目采用B/S加C/S 混合结构模式。财政局Web服务器上架设数据同步接收装置,由市属单位每天下班前把财务信息通过HTTP协议上传至财政局中心服务器,与Web服务器上的 接收装置对接。财政局内部各部门需要查阅大量财务信息,获取完备的市属单位当前财务状况信息,各部门按职能划分,需要准确的获取各部门各自所关注的汇总信 息,以财政报表的形式提供。
因财政数据量大,实时计算财政报表速度较慢,当初就考虑用报表缓存来减轻服务器的负担,但用缓存需要一 个合理的缓存更新机制。考虑到各市属单位每天下班前才把财务数据上传,财政局每天所查看到的财务信息其实并不包括当天(除非有某位领导等到所属单位全部上 传完之后才来查看信息,应该已经下班了),所以要是能实现任务计划调度,在每晚深夜把当天及历史财务信息汇总,更新缓存,速度瓶颈不就解决了吗。
当时由于系统核心是基于Web部署的,报表计算引擎也相应的部署在Tomcat容器上,因此如果想要借用Windows的任务计划来实现定时计算,就需 要额外编写普通桌面应用程序接口,稍显复杂。于是就琢磨着想在Web上实现,经过查阅较多相关资料,发现Java定时器 (java.util.Timer)有定时触发计划任务的功能,通过配置定时器的间隔时间,在某一间隔时间段之后会自动有规律的调用预先所安排的计划任务 (java.util.TimerTask)。另外,由于我们希望当Web工程启动时,定时器能自动开始计时,在整个Web工程的生命期里,定时器能在每 晚深夜触发一次报表计算引擎。因此定时器的存放位置也值得考查,不能简单的存在于单个Servlet或JavaBean中,必须能让定时器宿主的存活期为 整个Web工程生命期,在工程启动时能自动加载运行。结合这两点,跟Servlet上下文有关的侦听器就最合适不过了,通过在工程的配置文件中加以合理配 置,会在工程启动时自动运行,并在整个工程生命期中处于监听状态。
下面就Servlet侦听器结合Java定时器来讲述整个实现过程。 要运用Servlet侦听器需要实现javax.servlet.ServletContextListener接口,同时实现它的 contextInitialized(ServletContextEvent event)和contextDestroyed(ServletContextEvent event)两个接口函数。考虑定时器有个建立和销毁的过程,看了前面两个接口函数,就不容置疑的把建立的过程置入 contextInitialized,把销毁的过程置入contextDestroyed了。
我把ServletContextListener的实现类取名为ContextListener,在其内添加一个定时器,示例代码如下所示(为考虑篇幅,仅提供部分代码供读者参考):
java 代码 4
  1. private java.util.Timer timer = null;
  2. public void contextInitialized(ServletContextEvent event) {
  3. timer = new java.util.Timer(true);
  4. event.getServletContext().log("定时器已启动");
  5. timer.schedule(new MyTask(event.getServletContext()), 0, 60*60*1000);
  6. event.getServletContext().log("已经添加任务调度表");
  7. }
  8. public void contextDestroyed(ServletContextEvent event) {
  9. timer.cancel();
  10. event.getServletContext().log("定时器销毁");
  11. }
以上代码中, 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。示例代 码如下所示:
java 代码 5
  1. private static final int C_SCHEDULE_HOUR = 0;
  2. private static boolean isRunning = false;
  3. private ServletContext context = null;
  4. public MyTask(ServletContext context) {
  5. this.context = context;
  6. }
  7. public void run() {
  8. Calendar cal = Calendar.getInstance();
  9. if (!isRunning) {
  10. if (C_SCHEDULE_HOUR == cal.get(Calendar.HOUR_OF_DAY)) {
  11. isRunning = true;
  12. context.log("开始执行指定任务");
  13. //TODO 添加自定义的详细任务,以下只是示例
  14. int i = 0;
  15. while (i++ < 10) {
  16. context.log("已完成任务的" + i + "/" + 10);
  17. }
  18. isRunning = false;
  19. context.log("指定任务执行结束");
  20. }
  21. } else {
  22. context.log("上一次任务执行还未结束");
  23. }
  24. }
上面代码中"//TODO……"之下四行是真正被调度执行的演示代码(在我的财政数据中心项目中就是报表计算过程),您可以换成自己希望执行的语句。
到这儿,ServletContextListener和MyTask的代码都已完整了。最后一步就是把ServletContextListener部署到您的Web工程中去,在您工程的web.xml配置文件中加入如下三行:
123XML 配置代码
     <listener> 
          <listener-class> com.test.ContextListener </listener-class>
    </listener>  
当然,上面的com.test得换成您自己的包名了。保存web.xml文件后,把工程打包部署到Tomcat中即可。任务会在每晚12点至凌晨1点之间被执行,上面的代码会在Tomcat的日志文件中记录如下:
  1. 2003-12-05 0:21:39 开始执行指定任务
  2. 2003-12-05 0:21:39 已完成任务的1/10
  3. ……
  4. 2003-12-05 0:21:39 已完成任务的10/10
  5. 2003-12-05 0:21:39 指定任务执行结束
以上代码在Tomcat 4.1.29以及Tomcat 5.0.16上调试通过。

转载于:https://blog.51cto.com/nanhaochen/45593

Web定时器 - Timer相关推荐

  1. java web定时器_java的web项目中使用定时器 | 学步园

    之前接触过程序中的定时任务,但是没去自己亲自尝试过.终于这次抽空搞了一下.(一定要自己去操作,才能长经验,光看到过是没用的) 以下是两种方法,我使用的是监听的方法. JAVA WEB定时器,定时器的启 ...

  2. 【Android 异步操作】Timer 定时器 ( Timer 与 TimerTask 基本使用 | Timer 定时器常用用法 | Timer 源码分析 )

    文章目录 一.Timer 定时器基本使用 二.Timer 定时器常用用法 三.Timer 源码分析 四.Timer 部分源码注释 五.源码及资源下载 参考文档 : Timer 定时器 API 文档 T ...

  3. Java定时器Timer

    Java定时器Timer 在JDK库中,Timer类主要负责计划任务的功能,也就是在指定的时开始执行某一个任务.Timer类的主要作用就是设置计划任务,但封装任务的类却是TimerTask类,执行计划 ...

  4. python定时器 是线程吗_python线程定时器Timer(32)

    相对前面几篇python线程内容而言,本片内容相对比较简单,定时器 – 顾名思义,必然用于定时任务. 一.线程定时器Timer原理 原理比较简单,指定时间间隔后启动线程!适用场景:完成定时任务,例如: ...

  5. python定时器timer_python通过线程实现定时器timer的方法

    本文实例讲述了python通过线程实现定时器timer的方法.分享给大家供大家参考.具体分析如下: 这个python类实现了一个定时器效果,调用非常简单,可以让系统定时执行指定的函数 下面介绍以thr ...

  6. 第5章 定时器Timer

    第5章 定时器Timer 标签: Java多线程编程 <Java多线程编程核心技术> 个人笔记 第5章 定时器Timer 定时器Timer的使用 方法scheduleTimerTask t ...

  7. python中实现定时器Timer

    实现定时器最简单的办法是就是循环中间嵌time.sleep(seconds), 这里我就不赘述了 # encoding: UTF-8 import threading #Timer(定时器)是Thre ...

  8. Python 线程定时器 Timer - Python零基础入门教程

    目录 一.Python 线程定时器 Timer 原理 二.Python 线程定时器 Timer 使用 三.Python 线程定时器 Timer 总结 四.猜你喜欢 零基础 Python 学习路线推荐 ...

  9. 定时器Timer的实现

    定时器Timer的实现 定时器在实际项目中会用的比较平凡.因此,本文首先介绍定时器Timer的windows版本,跨平台的定时器将在下一篇文章中介绍.它们的源代码均用C++编写.源代码详见:https ...

最新文章

  1. 第一章 Mysql 简介及安装和配置
  2. R基于H2O包构建深度学习模型实战
  3. linux为3种人准备了权限,linux的3种特殊权限
  4. api服务器开发语言,【API编写】介绍一个国内强大的API接口文档写作网站showdoc - 最好的编程语言 - 博客园...
  5. 联想拯救者y空间兑换代码_锐祥贴片Y电容进入联想手机快充供应链,性能获世界500强认可...
  6. 工业机器人用铸铁牌号_常用铸铁牌号
  7. 第 3 章 镜像 - 015 - 调试 Dockerfile
  8. PHP网站源码-ThinkPHP5框架内核开发图书管理系统
  9. 在私企里,男工人能工作到退休年龄60岁吗?
  10. LVS负载均衡集群服务搭建详解(一)
  11. 智能家居如何让消费者心甘情愿地买单
  12. 奥维天地图解决办法!如何申请个人天地图API密钥?
  13. simulink教程(自动控制原理)
  14. uniapp仿淘宝--商品详情模板
  15. java中Graphics类的使用
  16. sgsn与ggsn的区别与联系
  17. 打印菱形图案用java如何做_Java打印出菱形图案
  18. 2019春第一周编程总结
  19. php同时接受get post,php中form表单同时使用POST和GET传递参数说明
  20. 计算机网络(第7版)谢希仁著 学习笔记 第四章网络层

热门文章

  1. 清空linux当前页面内容,linux文档整理
  2. hadoop中的9000端口代表什么_启动hadoop后,fs.defaultFS中配置的9000端口没有出现在监听中?...
  3. python框架flask_Python开发框架Flask-阿里云开发者社区
  4. android中屏保功能项目,【Android】一段时间不操作弹出【屏保】效果
  5. 程序员笔试网上查答案,HR吐槽,网友:你们公司断网开发吗?
  6. 函数节流你应该知道的那点事
  7. web前端开发是干嘛的?
  8. 掌握这8个CSS开发工具让你瞬间成为开发高手
  9. 谁不想写出干净的代码?7 个技巧,让你的同事爱上你的代码
  10. 转型HTML5前端工程师怎样学才能拿高薪?