我在使用两个 SingleThreadExecutor 线程和一个 FixedThreadPool 的 Google Web Toolkit 应用程序时遇到问题。我可以从 catalina.out 日志中看到线程没有被正确关闭,这导致 tomcat 进程继续运行:
INFO: Stopping service Catalina
Oct 30, 2012 2:16:48 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/btq] appears to have started a thread named [pool-4-thread-1] but has failed to stop it. This is very likely to create a memory leak.
Oct 30, 2012 2:16:48 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/btq] appears to have started a thread named [pool-5-thread-1] but has failed to stop it. This is very likely to create a memory leak.
Oct 30, 2012 2:16:48 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/btq] appears to have started a thread named [Thread-4] but has failed to stop it. This is very likely to create a memory leak.
我找到了一些关于使用 ServletContextListener 来处理这种事情的参考,但是我在让它在我的情况下工作时遇到了问题。
在一次尝试中,我将 ServletContextListener 添加到我的 GUIImpl 类中,该类是 GWT 代码的服务器端实现:
public class GUIImpl extends RemoteServiceServlet implements GUI, ServletContextListener
我想这可能不是通常的方式,但我尝试这样做是因为实例化 ExecutorService 的类位于另一个包中,该包包含与其他项目的一些共享代码。我的实现只是在其他类上调用了一些关闭函数,但我遇到了一些异常。
@Override
public void contextDestroyed(ServletContextEvent event) {
this.context = event.getServletContext();
context.log( "FUNCTION: GUIImpl.contextDestroyed - called" );
// Tell the Presenter to shut down
presenter.shutdown();
}
Presenter 类有一个 FileSystemMonitor 类的实例,它是实例化 Executor 的类。日志中的异常是:
Oct 30, 2012 2:16:48 PM org.apache.catalina.core.ApplicationContext log
INFO: FUNCTION: GUIImpl.contextDestroyed - called
Oct 30, 2012 2:16:48 PM org.apache.catalina.core.StandardContext listenerStop
SEVERE: Exception sending context destroyed event to listener instance of class com.mdaus.btq.gui.server.GUIImpl
java.lang.NullPointerException
at com.mdaus.btq.gui.server.GUIImpl.contextDestroyed(GUIImpl.java:1236)
at org.apache.catalina.core.StandardContext.listenerStop(StandardContext.java:4831)
at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5478)
at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232)
at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1575)
at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1564)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Oct 30, 2012 2:16:48 PM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: contextDestroyed()
Oct 30, 2012 2:16:48 PM org.apache.catalina.core.ApplicationContext log
INFO: ContextListener: contextDestroyed()
对不起,如果这个问题有点长而且令人困惑,但我现在有点困惑,因为我没有编写原始代码。
有人对我如何关闭这些线程有想法吗?