Der*_* Li 22 java tomcat java-ee tomcat7
我有一个部署到Tomcat服务器的WAR文件,其中一个类将在启动时调用,然后init()方法将安排一个计时器每5小时触发一次以执行某些任务.
我的init()代码如下所示:
public void init()
{
TimerTask parserTimerTask = new TimerTask() {
@Override
public void run() {
XmlParser.parsePage();
}
};
Timer parserTimer = new Timer();
parserTimer.scheduleAtFixedRate(parserTimerTask, 0, PERIOD);
}
Run Code Online (Sandbox Code Playgroud)
我的应用程序运行没有问题,但当我使用/etc/init.d/tomcat7停止关闭Tomcat时,我检查日志(catalina.out)它有一个这样的条目:
严重:Web应用程序[/ MyApplication]似乎已经启动了一个名为[Timer-0]的线程,但未能阻止它.这很可能造成内存泄漏.
我明白这是由我安排计时器引起的,但我的问题是:
setDeamon
为true,所以定时器不应该阻止Tomcat关闭,而不是继续运行?谢谢!
UPDATE
我根据一些搜索和DaveHowes的答案将我的代码更改为以下内容.
Timer parserTimer;
TimerTask parserTimerTask;
public void init()
{
parserTimerTask = new TimerTask() {
@Override
public void run() {
XmlParser.parsePage();
}
};
parserTimer = new Timer();
parserTimer.scheduleAtFixedRate(parserTimerTask, 0, PERIOD);
}
@Override
public void contextDestroyed(ServletContextEvent arg0) {
Logger logger = Logger.getRootLogger();
logger.info("DETECT TOMCAT SERVER IS GOING TO SHUT DOWN");
logger.info("CANCEL TIMER TASK AND TIMER");
otsParserTimerTask.cancel();
otsParserTimer.cancel();
logger.info("CANCELING COMPLETE");
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
}
Run Code Online (Sandbox Code Playgroud)
现在我的新问题:
谢谢!
UPDATE
它不起作用.我在contextDestroyed()方法中放了一些日志语句,在关闭Tomcat之后,日志文件只有以下内容:
PowderGodAppWebService - > [2012年2月7日04:09:46] INFO(PowderGodAppWebService.java:45):: DETECT TOMCAT服务器即将关闭PowderGodAppWebService - > [2012年2月7日04:09:46] INFO(PowderGodAppWebService. java:46)::取消定时器任务和定时器
CANCELLING COMPLETE不在那里.
我还检查了正在运行的进程(我不是Linux专家,所以我只使用Mac的Activity Monitor.
固定
我改变了我的代码,parserTimer = new Timer(true);
以便我的计时器作为守护程序线程运行,因为contextDestroyed()
在Tomcat实际关闭后调用了.
"在向任何ServletContextListener通知上下文破坏之前,所有servlet和过滤器都将被销毁."
http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContextListener.html
Bal*_*usC 63
千万不能使用Timer
在Java EE的环境!如果任务抛出运行时异常,则整个Timer
程序将被终止并且不再运行.您基本上需要重新启动整个服务器以使其再次运行.此外,它对系统时钟的变化很敏感.
请ScheduledExecutorService
改用.它对任务中抛出的异常和系统时钟的变化都不敏感.您可以通过其shutdownNow()
方法关闭它.
以下是整个ServletContextListener
实现的外观示例(注意:web.xml
由于新@WebListener
注释,无需注册):
@WebListener
public class BackgroundJobManager implements ServletContextListener {
private ScheduledExecutorService scheduler;
@Override
public void contextInitialized(ServletContextEvent event) {
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new YourParsingJob(), 0, 5, TimeUnit.HOUR);
}
@Override
public void contextDestroyed(ServletContextEvent event) {
scheduler.shutdownNow();
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
31341 次 |
最近记录: |