2

私の webapp には、Tomcat がリロード時にこれらのうちの 2 つを停止できない 3 つのスレッドがあります。

SEVERE: Web アプリケーション [/myapp] は [Thread-8] という名前のスレッドを開始したようですが、停止できませんでした。これにより、メモリ リークが発生する可能性が非常に高くなります。mai 08, 2013 11:22:40 AM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads

これにより、リロードごとに CPU 使用率が上昇します。

以下は、Tomcat が停止に失敗するスレッドの 1 つです。

私の ServletContextListener に実装されたコードの一部:

public void contextInitialized(ServletContextEvent event)
{
    final UpdaterThread updaterThread = new UpdaterThread();
    updaterThread.start();
    event.getServletContext().setAttribute("updaterthread", updaterThread);
}

public void contextDestroyed(ServletContextEvent event)
{
    UpdaterThread updaterThread = (UpdaterThread) event.getServletContext().getAttribute("updaterthread");
    if (updaterThread != null)
    {
        updaterThread.stopUpdater();
        updaterThread.interrupt();
        updaterThread = null;
    }
}

UpdaterThread の重要な部分:

public class UpdaterThread extends Thread implements Runnable
{
    private boolean alive = true;

    @Override
    public void run()
    {
        while(true)
        {
            try
            {
                while (alive)
                {
                    doUpdate();
                    sleep(60*1000);
                }
            }
            catch (InterruptedException ie) {}
            catch (Exception e) {}
        }
    }

    public void stopUpdater()
    {
        alive = false;
    }
}

このスレッドが止まらない理由を誰か知っていますか? 特定の時間に何らかの作業を行うスレッドを実装するより良い方法はありますか?

4

3 に答える 3

0

この問題を修正するためのコードの小さな変更

public class UpdaterThread extends Thread implements Runnable
{
private boolean alive = true;

@Override
public void run()
{
    while(alive)
    {
        try
        {
            doUpdate();
            sleep(60*1000);
        }
        catch (InterruptedException ie) {
          //sleep interrupted
        }
        catch (Exception e) {
          // exception in doUpdate method ? must handle this
        }
    }
}

 public void stopUpdater()
 {
    alive = false;
 }
}

ただし、Sleepwhile ループでは、パフォーマンスの問題が発生する可能性があります。Thread.sleepスレッドをしばらく中断したい場合にのみ使用できます。何らかの状態を待ちたい場合は使用しないでください。

この SO の質問を確認してください: Thread-sleep-call-in-loop

于 2013-05-08T11:17:16.207 に答える