严重: The web application [] appears to have started a thread named [Thread-

时间:2024-10-30 18:20:17

 

/h/

 

1,获取dump


2,从dump找到正在运行的线程所属class


3,在myeclise 开启debug模式,给正在运行的方法加上断点


4,这时你会发现当停止application时,有一个线程还没有停止掉


5,在 AppContextListener 进行contextDestroyed时,要加一段额外的代码,用来我们关闭tomcat的时候可以同时关闭此线程



例如此例:


在tomcat7+quartz1.8/1.7 + spring3.0.5做定时任务的时候 , 当关闭tomcat时抛异常"严重: The web application [] appears to have started a thread named [Thread-":


ar 27, 2013 6:05:35 PM pause
INFO: Pausing ProtocolHandler ["http-nio-8082"]
Mar 27, 2013 6:05:35 PM stopInternal
INFO: Stopping service Catalina
Mar 27, 2013 6:05:35 PM clearReferencesThreads
SEVERE: The web application [/****] appears to have started a thread named [startQuertz_Worker-1] buthas       failed to stop it. This is very likely to create a memory leak.
Mar 27, 2013 6:05:35 PM clearReferencesThreads
SEVERE: The web application [/****] appears to have started a thread named [startQuertz_Worker-2] buthas  failed to stop it. This is very likely to create a memory leak.
Mar 27, 2013 6:05:35 PM clearReferencesThreads
SEVERE: The web application [/****] appears to have started a thread named [startQuertz_Worker-3] buthas   failed to stop it. This is very likely to create a memory leak.
Mar 27, 2013 6:05:35 PM clearReferencesThreads

原因:tomcat在shutdown做清理工作的时候没能等待quartz完成cleanShutdown。就是tomcat太心急了,说 “quartz  , 我关门了,你走吧!”,还没等quartz反应过来,就要关大门,这时发现 “quartz , 你怎么还在这儿呀!”。


解决办法:自己实现一个ServletContextListener,在contextDestroyed的时候主动调用quartz schedular的shutdown方法,并且主线程sleep一会儿.


代码:
public class QuartzContextListener implements ServletContextListener {

    /*
     * 测试代码写得随便
     * 
     * @#contextDestroyed(.
     * ServletContextEvent)
     */
    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        WebApplicationContext webApplicationContext = (WebApplicationContext) arg0
                .getServletContext()
                .getAttribute(
                        WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
         startQuertz = () webApplicationContext
                .getBean("startQuertz");
        if(startQuertz != null) {
            ();
        }
        try {
            (1000);
        } catch (InterruptedException e) {
            ();
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * #contextInitialized(
     * .ServletContextEvent)
     */
    @Override
    public void contextInitialized(ServletContextEvent arg0) {
<span style="white-space:pre">        </span>//不做任何事情
    }

}

最后在 配置QuartzContextListener。



注意:如果tomcat在Dameon模式下,以上方法不起作用,请参考:
/tomcat/MemoryLeakProtection