ServletContextListener线程

时间:2011-03-06 18:55:35

标签: servlets

我目前遇到了在webachive中停止后台线程的问题。我目前将其绑定在war的部署中,并在取消部署存档时销毁它。

线程启动没有问题,但是当我关闭存档时,它似乎丢失了线程上的句柄。在下面的情况中:st方法在调用contextDestroyed方法时为空。

这是一个问题,因为Tomcat在其关于内存泄漏的警告中注意到该线程是孤立的。

public class LimitOrderContextListener implements ServletContextListener {

    static Logger logger = Logger.getLogger(LimitOrderRuntime.class.getName());
    private SwiftThread st = null;

    /**
     * Initializes this listener when this war's context is initialized
     */
    public void contextInitialized(ServletContextEvent sce) 
    {
        try {
            if ( (st == null) || (!st.isAlive()) )  {
                LimitOrderRuntime lor = new LimitOrderRuntime();
                SwiftThread st = new SwiftThread(lor);
                st.start();
            } else {
                st.gracefulStop();
                st.join(2000);
            }
        } catch(Exception e)    {
            logger.warn("Unable to properly load thread! " + 
                    e.getMessage() + " --cause " + e.getCause());
            e.printStackTrace();
        }

    }

    /**
     * When this war is destroyed/stopped, stop the thread.
     */
    public void contextDestroyed(ServletContextEvent sce) 
    {
        try {
            boolean success = st.gracefulStop();
            if (!success)   {
                st.interrupt();
            }
        } catch (Exception e)   {
            logger.warn("Unable to properly release thread! " + 
                    e.getMessage() + " --cause " + e.getCause());
            e.printStackTrace();
        }    
    }

}

1 个答案:

答案 0 :(得分:1)

在你的contextInitialized方法中,你将st重新声明为局部变量,而不是用线程初始化实例变量。

替换

SwiftThread st = new SwiftThread(lor);

this.st = new SwiftThread(lor);