简体   繁体   中英

Tomcat fails to stop thread in webapp

In my webapp I have 3 threads where tomcat fails to stop 2 of these on reload.

SEVERE: The web application [/myapp] appears to have started a thread named [Thread-8] but has failed to stop it. This is very likely to create a memory leak. mai 08, 2013 11:22:40 AM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads

This causes the CPU usage to rise for each reload.

Here is one of the threads that tomcat fails to stop:

Some of the code implemented in my 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;
    }
}

And the important parts of 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;
    }
}

Does anyone have any idea why this thread don't stops? Is there a better way to implement a thread doing some work at specific times?

As far as I can see, you're not actually stopping your thread at all. You have two while loops, and you only stop the inner when you set alive = false . The outer will run forever, doing nothing. You also don't handle the interrupt your sending, so that won't terminate the thread either.

I would instead do something like this:

public void run()
{
    while(alive)
    {
        try
        {
            doUpdate();
            sleep(60*1000);
        }
        catch (InterruptedException ie) {
            alive = false;
        }
    }
} 

Also, if you give your thread a proper name when creating it, you'll see if it's actually that thread that is causing the problem Tomcat is reporting.

it's related to ThreadLocal issues with tomcat, Check this document http://wiki.apache.org/tomcat/MemoryLeakProtection

Mar 16, 2010 11:47:24 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap SEVERE: A web application created a ThreadLocal with key of type [test.MyThreadLocal] (value [test.MyThreadLocal@4dbb9a58]) and a value of type [test.MyCounter] (value [test.MyCounter@57922f46]) but failed to remove it when the web application was stopped. To prevent a memory leak, the ThreadLocal has been forcibly removed.

http://forum.springsource.org/showthread.php?84202-Installation-ThreadLocal-forcefully-removed

A Small change in your code to fix this issue

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;
 }
}

However, Sleep in while loop likely to create a performance issue. You could use Thread.sleep only if you want to suspend your thread for some time. Do not use it if you want to wait for some condition.

Check this SO question : Thread-sleep-called-in-loop

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM