实现方法:
先在web.xml中添加一个listener,指定自己写好的类;写好的类实现ServletContextListener接口,重写contextInitialized方法,并在方法里执行所需的任务;由于是定时任务,需要再创建一个类继承TimerTask,并在重写方法run中,写入要执行的任务。具体示例如下:
web.xml(可根据自己的项目及习惯更改路径和类名)
com.ps.filter.StartupListener
StartupListener.class
package com.ps.filter;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class StartupListener implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent sce) {
sce.getServletContext().log("定时器销毁");
}
@Override
public void contextInitialized(ServletContextEvent sce) {
sce.getServletContext().log("启动线程池");
sce.getServletContext().log("启动定时器");
//自JDK5之后,用ScheduledThreadPoolExecutor来替代Timer,建一个对象设置其容量为5,可同时进行5个任务
ScheduledThreadPoolExecutor stpe = new ScheduledThreadPoolExecutor(5);
//这个类为自定义的类
MyTimerTask myTimerTask = new MyTimerTask(sce.getServletContext());
//stpe.scheduleAtFixedRate(myTimerTask, 5, 300, TimeUnit.SECONDS);
stpe.scheduleWithFixedDelay(myTimerTask, 5, 300, TimeUnit.SECONDS);
}
}
上述代码中底部出现了scheduleWithFixedDelay和scheduleAtFixedRate方法,都是以执行任务为基准,这两个方法在示例中传参相同,都是先传对象方法;再传项目运行后多长时间运行第一次;再传第一次后每次项目运行的间隔时间;最后是时间类型。示例中取时间类型是秒,解释起来就是项目启动5秒后执行myTimerTask中的任务,之后每过300秒执行一次。
其中scheduleWithFixedDelay和scheduleAtFixedRate方法有很明显的区别,使用时需要特别注意。
以上述代码为例,scheduleWithFixedDelay方法是以任务完成为首要条件。第一次执行完任务后,过了300秒再执行任务。若执行任务的时间为30分钟,则首次30分钟的任务完成后,再过300秒执行第二次任务。
而scheduleAtFixedRate方法,是以任务次数为首要条件。在间隔时间没有进行的任务会累计次数,并在任务执行结束后,继续跑累计的任务。以上述代码为例,若首次执行任务的时间为30分钟,代码中写每过300秒执行一次任务,则首次任务执行后,会立即执行下一次任务,此时后台累计剩余执行任务的次数为5次(300秒等于5分钟,30分钟则累计6次,第一次任务执行结束后第二次立即执行,所以剩余次数为5次)。
若想同时进行多个任务,则通过ScheduledThreadPoolExecutor所建的对象 ,在执行方法即可,任务数最好不要超过设定的值。如要同时执行3个不同任务,方法规则如上所述,写法如下:
stpe.scheduleWithFixedDelay(myTimerTask1, 5, 300, TimeUnit.SECONDS);
stpe.scheduleWithFixedDelay(myTimerTask2, 5, 300, TimeUnit.SECONDS);
stpe.scheduleWithFixedDelay(myTimerTask3, 5, 300, TimeUnit.SECONDS);
MyTimerTask.class
package com.ps.filter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.TimerTask;
import javax.servlet.ServletContext;
import com.ps.util.ResolveNum;
public class MyTimerTask extends TimerTask {
private ServletContext context = null;
// private int param;
public MyTimerTask4analysisReport(ServletContext context) {
this.context = context;
}
@Override
public void run() {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
context.log(format.format(new Date()) + "执行指定定時任务开始---下载分析报告");
// 此处为需要执行的任务(可根据需求写入指定的任务)
ResolveNum num = new ResolveNum();
num.Narcissus();
//任务结束
context.log(format.format(new Date()) + "指定定時任务执行结束---下载分析报告");
}
}
此篇实现方法源自互联网搜索,整理测试后的总结,亲测有效可用。