关闭tomcat时停止计划的计时器[重复]

我已将一个WAR文件部署到Tomcat服务器,该类之一将在启动时调用,然后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);

}

我的应用程序运行没有问题,但是当我使用

关闭Tomcat时,我检查了日志(catalina.out),它具有以下条目:

我了解这是由我安排计时器引起的,但我的问题是:

  1. 我没有设置setDeamon为true,所以计时器是否不应该阻止Tomcat关闭而不是保持运行?
  2. 我可以在我的应用程序中检测到Tomcat将要关闭并取消计时器吗?
  3. 我可以使用其他哪些解决方案来解决此问题?

谢谢!

根据一些搜索和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) {

}

现在我的新问题是:

  1. 我先取消TimerTask然后取消Timer,这正确吗?
  2. 我还有其他事要做吗?

谢谢!

没用 我将一些日志记录语句放入contextDestroyed()方法中,在关闭Tomcat之后,日志文件仅具有以下内容:

PowderGodAppWebService-> [2012年2月7日04:09:46

PM]信息(PowderGodAppWebService.java:45):: DETECT

TOMCAT服务器即将关闭PowderGodAppWebService-> [2012年2月7日04:09:46 PM]

INFO(PowderGodAppWebService。 java:46)::取消计时器任务和计时器

不存在。

我还检查了正在运行的进程(我不是Linux专家,所以我只使用Mac的活动监视器。

  • 确保没有Java进程正在运行
  • 启动Tomcat,注意该Java进程的PID
  • 停止Tomcat
  • 发现Tomcat进程不见了
  • 启动Tomcat,注意该Java进程的PID
  • 部署我的战争档案
  • 对过程进行采样,请参见[Timer-0]线程
  • 关闭Tomcat
  • 发现该过程仍然存在
  • 采样过程
  • 看到[Timer-0]还在

我将代码更改为,parserTimer=newTimer(true);以便计时器作为守护程序线程运行,因为contextDestroyed()在Tomcat实际上关闭后调用了gets。

“在通知任何ServletContextListener上下文破坏之前,所有Servlet和过滤器都将被破坏。”

http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContextListener.html

回答:

千万 使用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();

}

}

以上是 关闭tomcat时停止计划的计时器[重复] 的全部内容, 来源链接: utcz.com/qa/397405.html

回到顶部