好多朋友用过Windows的任务计划 也有不少程序迷自己曾写过时钟报警 系统自动关机等趣味程序 可却很少有朋友在Web工程中实现过类似功能
当Web工程启动时 定时器能自动开始计时 在整个Web工程的生命期里 定时器能在每晚深夜触发一次任务 因此定时器的存放位置也值得考查 不能简单的存在于单个Servlet或JavaBean中 必须能让定时器宿主的存活期为整个Web工程生命期 在工程启动时能自动加载运行 结合这两点 跟 Servlet上下文有关的侦听器就最合适不过了 通过在工程的配置文件中加以合理配置 会在工程启动时自动运行 并在整个工程生命期中处于监听状态
下面就Servlet侦听器结合Java定时器来讲述整个实现过程 要运用Servlet侦听器需要实现 javax servlet ServletContextListener接口 同时实现它的contextInitialized (ServletContextEvent event)和contextDestroyed(ServletContextEvent event)两个接口函数 考虑定时器有个建立和销毁的过程 看了前面两个接口函数 就不容置疑的把建立的过程置入 contextInitialized 把销毁的过程置入contextDestroyed了
我把ServletContextListener的实现类取名为ContextListener 在其内添加一个定时器 示例代码如下所示
import java util Timer
import javax servlet ServletContextEvent
import javax servlet ServletContextListener
import javax servlet ServletException
import javax servlet ServletRequest
import javax servlet ServletResponse
import javax servlet HttpServlet
public class ContextListener
extends HttpServlet
implements ServletContextListener {
public ContextListener() {
}
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()) * * )
event getServletContext() log( 已经添加任务调度表 )
}
public void contextDestroyed(ServletContextEvent event) {
timer cancel()
event getServletContext() log( 定时器销毁 )
}
}
以上代码中 timer schedule(new MyTask(event getServletContext()) * * )这一行为定时器调度语句 其中MyTask是自定义需要被调度的执行任务(在我的财政数据中心项目中就是报表计算引擎入口) 从 java util TimerTask继承 下面会重点讲述 第三个参数表示每小时(即 * * 毫秒)被触发一次 中间参数 表示无延迟 其它代码相当简单 不再详细说明
下面介绍MyTask的实现 上面的代码中看到了在构造MyTask时 传入了javax servlet ServletContext类型参数 是为记录Servlet日志方便而传入 因此需要重载MyTask的构造函数(其父类java util TimerTask原构造函数是没有参数的) 在timer schedule()的调度中 设置了每小时调度一次 因此如果想实现调度任务每 小时被执行一次 还需要判断一下时钟点 以常量C_SCHEDULE_HOUR表示(晚上 点 也即 点) 同时为防止 小时执行下来 任务还未执行完(当然 一般任务是没有这么长的) 避免第二次又被调度以引起执行冲突 设置了当前是否正在执行的状态标志isRunning 示例代码如下所示
import java util *
import javax servlet ServletContextEvent
import javax servlet ServletContextListener
import javax servlet ServletException
import javax servlet ServletRequest
import javax servlet ServletResponse
import javax servlet HttpServlet
import javax servlet *
public class MyTask extends TimerTask {
private static final int C_SCHEDULE_HOUR =
private static boolean isRunning = false
private ServletContext context = null
public MyTask() {
}
public MyTask(ServletContext context) {
ntext = 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 添加自定义的详细任务 以下只是示例
//系统定时接收邮件
Email email=new Email()
email recieve()
isRunning = false
context log( 指定任务执行结束 )
}
}
else {
context log( 上一次任务执行还未结束 )
}
}
}
到这儿 ServletContextListener和MyTask的代码都已完整了 最后一步就是把ServletContextListener部署到您的Web工程中去 在您工程的web xml配置文件中加入如下三行
<listener>
<listener class>test ContextListener</listener class>
</listener>
lishixinzhi/Article/program/Java/hx/201311/26421java中设置定时任务用Timer类可以实现。
一、延时执行
首先,我们定义一个类,给它取个名字叫TimeTask,我们的定时任务,就在这个类的main函数里执行。代码如下:
package test
import java.util.Timer
public class TimeTask {
public static void main(String[] args){
Timer timer = new Timer()
timer.schedule(new Task(), 60 * 1000)
}
}
解释一下上面的代码。
上面的代码实现了这样一个功能,当TimeTask程序启动以后,过一分钟后执行某项任务。很简单吧:先new一个Timer对象,然后调用它的schedule方法,这个方法有四个重载的方法,这里我们用其中一个,
public void schedule(TimerTask task,long delay)
首先,第一个参数
第一个参数就是我们要执行的任务。
这是一个TimerTask对象,确切点说是一个实现TimerTask的类的对象,因为TimerTask是个抽象类。上面的代码里面,Task就是我们自己定义的实现了TimerTask的类,因为是在同一个包里面,所以没有显性的import进来。Task类的代码如下
package test
import java.util.TimerTask
public class Task extends TimerTask {
public void run(){
System.out.println("定时任务执行")
}
}
我们的Task必须实现TimerTask的方法run,要执行的任务就在这个run方法里面,这里,我们只让它往控制台打一行字。
第二个参数
第二个参数是一个long型的值。这是延迟的时间,就是从程序开始以后,再过多少时间来执行定时任务。这个long型的值是毫秒数,所以前面我们的程序里面,过一分钟后执行用的参数值就是 60 * 1000。
二、循环执行
设置定时任务的时候,往往我们需要重复的执行这样任务,每隔一段时间执行一次,而上面的方法是只执行一次的,这样就用到了schedule方法的是另一个重载函数
public void schedule(TimerTask task,long delay,long period)
前两个参数就不用说什么了,最后一个参数就是间隔的时间,又是个long型的毫秒数(看来java里涉及到时间的,跟这个long是脱不了干系了),比如我们希望上面的任务从第一次执行后,每个一分钟执行一次,第三个参数值赋60 * 1000就ok了。
三、指定执行时间
既然号称是定时任务,我们肯定希望由我们来指定任务指定的时间,显然上面的方法就不中用了,因为我们不知道程序什么时间开始运行,就没办法确定需要延时多少。没关系,schedule四个重载的方法还没用完呢。用下面这个就OK了:
public void schedule(TimerTask task,Date time)
比如,我们希望定时任务2006年7月2日0时0分执行,只要给第二个参数传一个时间设置为2006年7月2日0时0分的Date对象就可以了。
有一种情况是,可能我们的程序启动的时候,已经是2006年7月3日了,这样的话,程序一启动,定时任务就开始执行了。
schedule最后一个重载的方法是
public void schedule(TimerTask task,Date firstTime,long period)
1、创建ScheduledExecutorService对象,用于执行定时任务。2、使用scheduleAtFixedRate()方法来设置定时任务,该方法可以指定任务的初始延迟时间、任务运行周期等参数。
3、在定时任务的run()方法中编写任务代码,实现需要执行的业务逻辑。
4、在程序启动时,调用ScheduledExecutorService对象的shutdown()方法来关闭定时任务。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)