首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

JAVA WEB服务监听与周期施行某一任务

2012-09-22 
JAVA WEB服务监听与周期执行某一任务说明:本人为菜鸟,此文主要用于记录个人学习笔记,也希望给予同时菜鸟的

JAVA WEB服务监听与周期执行某一任务
说明:本人为菜鸟,此文主要用于记录个人学习笔记,也希望给予同时菜鸟的朋友一点帮助,文中解决方法有些采用了他人文章,感谢原创者的付出。由于其他原因,本人只给出本人查阅采用的文章链接,对于参考文章非该作者原创的情况,希望原创者能够理解。
应用背景:在做一个java web工程服务器为tomcat,里面有个功能大致要求如下,周期性的检查计算机目录下的某个文件是否更新,若更新则对该文件进行分析。
关键词:ServletContextListener;Timer;TimerTask
解决方法:
    搜索资料后,发现采用ServletContextListener接口能够监听ServletContext对象的生命周期,实际上就是监听Web应用的生命周期。当Servlet容器启动或终止Web应用时,会触发ServletContextEvent事件,该事件由ServletContextListener 来处理。这样我们可以根据这个特性实现在web应用程序初始化时,自动运行一些初始化程序。在 ServletContextListener 接口中定义了处理ServletContextEvent事件的两个方法。该接口中有两个主要方法:contextDestroyed()与contextInitialized(),前者由Servlet容器调用在web应用的“初始化”阶段,后者的调用在web应用的“结束”阶段。在部署ServletContextListene的时候,需要在web.xml中对相关参数进行配置,相关更详细地信息,可以自行搜索。现就本文具体代码进行分析。
首先是web.xml


<listener-class>用于设定执行监听的类,后面的<param-name>和<param-value>用来设定后续schedule()方法中所需的周期。

Analyze.java
import java.util.List;import java.util.TimerTask;import javax.servlet.ServletContext;import wstate.State;public class NewTask extends TimerTask {public NewTask(ServletContext servletContext) {this.servletContext = servletContext;}private ServletContext servletContext = null;private static boolean isRunning = false; // 运行标志(表示是否正在运行计划的任务)@Overridepublic void run() {if (!isRunning) { // 当未执行此任务时则开始执行List<State> l = NodesAnalysis.GetStates();if (l.size() != 0) {servletContext.setAttribute("states", l);}isRunning = false; // 将任务执行标志设置为执行完毕} else {System.out.println("任务正在运行中");}}}

对于Timer和TimerTask的介绍,个人觉得http://hi.baidu.com/wmqxyh/item/a386395ba03db50ce6c4a5a9所写非常详细,贴出来,感谢该作者:
Timer与TimerTask都在java.util包中,它们是与任务调度相关的类。Timer是一个定时器,可以设置成在特定时间或按特定时间周期产生信号;TimerTask负责定义所要执行的任务。将Timer和TimerTask关联起来,在Timer发出信号的时候执行TimerTask定义的任务。 TimerTask是一个抽象类,只要继承TimerTask类并实现run()方法就行了。run()方法体就是定义所要执行的任务的地方,在Timer发出信号的时候,这个run()方法就会执行。要想知道本次run()方法再何时被启动,可以使用TimerTask类中的方法long scheduledExecutionTime(),使用这个方法不会造成时间精度的误差,它比System.currentTimeMillis()更节省资源。 可以通过Timer类的schedule(...)方法来设定发出信号的特定时间或特定时间周期,并与一个TimerTask类的实例相关联。使用void scheduleAtFixedRate(...)方法可以产生固定周期信号。可以使用Timer类的cancle()方法停止Timer,不再发出信号,此时,Timer与TimerTask也就脱离关系了。也可以通过TimerTask类中的cancle()方法达到同样的目的。 有一个问题,如果run()方法里面的任务在下一次信号出现之前还没有完成怎么办?有下面两种情况:(1)在用schedule(...)方法调度时:如果run()方法里面的任务在信号周期之内完成,那么下一次的信号就会在预定的时间产生;如果run()方法里面的任务在下一次信号出现之前还没有完成,那么下一次的信号就会延迟,并且上一个run()执行完成之后就立即产生下一个信号,下一个run()立即开始执行。(2)在用scheduleAtFixedRate(...)方法调度时:如果run()方法里面的任务在信号周期之内完成,那么下一次的信号就会在预定的时间产生;如果run()方法里面的任务在下一次信号出现之前还没有完成,那么等到run()执行完成之后,下一次的信号产生就尽量赶上本应该产生信号的时间,意思就是如果有累计的(从第一次信号算起)超时存在,那么下一次的信号就会在run()方法执行完之后立即产生;如果没有累计的超时存在,那么就按照周期产生信号。 另外,根据规范,如果调用cancle()时run()仍在执行,那么run()会继续执行直到完成。
感谢以下作者的辛勤劳动。
http://www.cnblogs.com/soarwell/archive/2009/03/18/1415206.html
http://www.cnblogs.com/secret1998/archive/2010/05/26/1744432.html
http://blog.csdn.net/blueling51/article/details/6931026
http://hi.baidu.com/wmqxyh/item/a386395ba03db50ce6c4a5a9

热点排行