实现方法:
先在web.xml中添加一个listener,指定自己写好的类;写好的类实现ServletContextListener接口,重写contextInitialized方法,并在方法里执行所需的任务;由于是定时任务,需要再创建一个类继承TimerTask,并在重写方法run中,写入要执行的任务。具体示例如下:
web.xml(可根据自己的项目及习惯更改路径和类名)
<listener> <listener-class>com.ps.filter.StartupListener</listener-class> </listener>
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()) + "指定定時任务执行结束---下载分析报告"); } }
此篇实现方法源自互联网搜索,整理测试后的总结,亲测有效可用。