我有一個WAR文件部署到Tomcat服務器,其中一個類將在啓動時被調用,然後init()方法將計劃一個計時器每5小時執行一次任務。關閉tomcat時停止計劃的定時器
我的init()的代碼如下所示:
public void init()
{
TimerTask parserTimerTask = new TimerTask() {
@Override
public void run() {
XmlParser.parsePage();
}
};
Timer parserTimer = new Timer();
parserTimer.scheduleAtFixedRate(parserTimerTask, 0, PERIOD);
}
我的應用程序運行沒有問題,但是當我關閉使用Tomcat的/etc/init.d/tomcat7停止,然後我檢查日誌(catalina.out)它有這樣一個條目:
SEVERE:Web應用程序[/ MyApplication]似乎啓動了一個名爲[Timer-0]的線程,但未能阻止它。這很可能造成內存泄漏。
我明白這是由我造成的安排計時器,但我的問題是:
- 我沒有設置
setDeamon
爲true,所以不宜定時器防止從Tomcat的關停,而不是左跑? - 我可以在我的應用程序中檢測到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) {
}
現在我的新問題:
- 我取消TimerTask的第一則計時器,這是正確的?
- 我還有其他事情要做嗎?
謝謝!
UPDATE
它不工作。我在contextDestroyed()方法中放了一些日誌語句,在我關閉Tomcat之後,日誌文件只有如下內容:
PowderGodAppWebService - > [Feb Feb 2012 04:09:46 PM] INFO(PowderGodAppWebService.java:45 ):: DETECT TOMCAT服務器將SHUT DOWN PowderGodAppWebService - > [2012年2月7日下午4時09分46秒] INFO(PowderGodAppWebService.java:46):: CANCEL計時器任務和定時器
消除COMPLETE是不在那裏。
我也檢查正在運行的進程(我不是Linux專家,所以我只是使用Mac的活動監視器。
- 確保沒有java進程正在運行
- 啓動Tomcat,請注意,java進程的PID
- 停止Tomcat
- 找到Tomcat進程走了
- 啓動Tomcat,注意的PID該Java進程
- 部署我的war文件
- 樣品的過程中,看到[定時器0]線程是有
- 關機的Tomcat
- 發現該工藝仍然存在
- 樣品過程
- 參見[計時器0]仍然存在
FIXED
我改變代碼parserTimer = new Timer(true);
所以我的計時器作爲守護程序線程運行,因爲在Tomcat實際關閉後調用contextDestroyed()
。
「所有的servlet和過濾器將所有的ServletContextListener通知情況下破壞之前已被銷燬。」
http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContextListener.html
如果不是那些CANCEL請求在contextDestroyed()? – DaveH 2012-02-07 08:51:50
是的......我想是時候睡覺了,謝謝指出! – 2012-02-07 08:52:54
TimerTask#取消不會中斷任務,如果它正在運行 - 它只會確保它永遠不會再運行 - 但除此之外,我會說你會沒事的那 – DaveH 2012-02-07 08:55:17