[英]Tomcat fails to stop thread in webapp
In my webapp I have 3 threads where tomcat fails to stop 2 of these on reload. 在我的webapp中,我有3个线程,其中tomcat无法在重新加载时阻止其中2个线程。
SEVERE: The web application [/myapp] appears to have started a thread named [Thread-8] but has failed to stop it.
严重:Web应用程序[/ myapp]似乎已启动名为[Thread-8]的线程,但未能停止它。 This is very likely to create a memory leak.
这很可能造成内存泄漏。 mai 08, 2013 11:22:40 AM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
mai 08,2013 11:22:40 AM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
This causes the CPU usage to rise for each reload. 这会导致每次重新加载时CPU使用率都会上升。
Here is one of the threads that tomcat fails to stop: 这是tomcat无法停止的线程之一:
Some of the code implemented in my ServletContextListener: 在我的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: 还有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
. 您有两个
while
循环,并且仅当您设置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. 您也不会处理发送
interrupt
,因此也不会终止线程。
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. 另外,如果在创建线程时给它一个适当的名称,您将看到实际上是该线程引起了Tomcat报告的问题。
it's related to ThreadLocal issues with tomcat, Check this document http://wiki.apache.org/tomcat/MemoryLeakProtection 它与tomcat的ThreadLocal问题有关,请查看此文档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.
2010年3月16日,下午11:47:24 org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap严重:一个Web应用程序创建了一个ThreadLocal,其键值为[test.MyThreadLocal]类型(值[test.MyThreadLocal@4dbb9a58])和一个值类型[test.MyCounter](值[test.MyCounter@57922f46]),但在停止Web应用程序时无法将其删除。 To prevent a memory leak, the ThreadLocal has been forcibly removed.
为了防止内存泄漏,已将ThreadLocal强制删除。
http://forum.springsource.org/showthread.php?84202-Installation-ThreadLocal-forcefully-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. 但是,在while循环中
Sleep
可能会导致性能问题。 You could use Thread.sleep
only if you want to suspend your thread for some time. 仅当您想要暂停线程一段时间时才可以使用
Thread.sleep
。 Do not use it if you want to wait for some condition. 如果要等待某种情况,请勿使用它。
Check this SO question : Thread-sleep-called-in-loop 检查此SO问题: 线程睡眠称为循环
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.