WARファイルがTomcatサーバーにデプロイされているときに、クラスの1つが起動時に呼び出され、init()メソッドがタイマーをスケジュールして、 。シャットダウン時にスケジュールされたタイマーを停止する
私の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とき、私はログを確認します
SEVERE:Webアプリケーション[/ MyApplication]が[Timer-0]という名前のスレッドを開始したように見えますが、停止できませんでした。これはメモリリークを引き起こす可能性が非常に高いです。
私は、これはタイマーをスケジュール私によって引き起こされる理解が、私の質問は:
- は私がtrueに
setDeamon
を設定しなかったので、タイマーではなく、シャットダウンから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
それは動作しません。 Tomcatをシャットダウンした後、contextDestroyed()メソッドにいくつかのロギングステートメントを入れます。ログファイルには次のものしかありません:
PowderGodAppWebService - > [07 Feb 2012 04:09:46 PM] INFO(PowderGodAppWebService.java:45) ):: TomcatサーバーがDOWN PowderGodAppWebService SHUTうとしているDETECT - COMPLETEをキャンセル> [2012年2月7日午前4時09分46秒PM] INFO(PowderGodAppWebService.java:46):: CANCEL TIMERタスクとTIMER
ですいない。
実行中のプロセスもチェックしました(私はLinuxのエキスパートではないため、Macのアクティビティモニタを使用しています)。
- そのJavaプロセスのPID
- Tomcatを停止
- はのPIDに注意し、Tomcatプロセスが
- Tomcatを起動してしまっているが見つかり注意し、何のJavaプロセスが
- スタートTomcatを実行されていないことを確認してくださいそのJavaプロセス
- 私の戦争ファイルを展開する
- [Timer-0]スレッドが存在することを参照してください。
- シャットダウンTomcatの
- プロセスは、プロセス
- 参照[タイマー-0]私は
parserTimer = new Timer(true);
に私のコードを変更し
FIXED
まだある
contextDestroyed()
はTomcatが実際にシャットダウンした後に呼び出されるからです。 "ServletContextListenersにコンテキスト破棄が通知される前に、すべてのサーブレットとフィルタが破棄されています。
http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContextListener.html
それらのキャンセルがが(contextDestroyedにすべきではない):ここでは
は全体
ServletContextListener
実装は(:新しい@WebListener
注釈へweb.xml
必要なおかげで無登録のノートが)のように見えることができる方法の例ですか? – DaveHはい...私はそれがベッドのための時間だと思う、指摘のおかげで! –
TimerTask#cancelは、現在実行中の場合はタスクを中断しません。再実行されないことを確認しますが、それ以外は、 – DaveH