java – 在停止Tomcat时,ExecutorService不会从contextDestroyed()关闭

前端之家收集整理的这篇文章主要介绍了java – 在停止Tomcat时,ExecutorService不会从contextDestroyed()关闭前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_404_1@我有一个ExecutorService executor = Executors.newSingleThreadExecutor();我想在服务器关闭时停止.

@H_404_1@我有一个实现ServletContextListener的类,它用@WebListener注释.

@H_404_1@我在该课程中有两种方法

@H_404_1@

@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
    System.out.println("ServletContextListener started");
}

@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
    executor.shutdown();
    executor.shutdownNow();
    System.out.println("ServletContextListener destroyed");
}
@H_404_1@而且我看到它在它们应该的时候打印出它们中的内容,但是当我在intelij中按下一次停止按钮时,我得到:

@H_404_1@

@H_404_1@SEVERE: The web application [] appears to have started a thread named [pool-2-thread-1] but has Failed to stop it. This is very likely to create a memory leak.

@H_404_1@在它打印出ServletContextListener之后就被销毁了.

@H_404_1@我需要再次按下停止按钮才能完全停止它.

@H_404_1@为什么它不会关闭ExecutorService,即使它到达executor.shutdown();?我究竟做错了什么?

@H_404_1@PS:这是我唯一的ExecutorService,没有其他线程由我制作.

@H_404_1@EDIT2:

@H_404_1@执行程序服务是单例类中的一个字段,它使用类初始化:

@H_404_1@

private ExecutorService executor = Executors.newSingleThreadExecutor();
@H_404_1@这是类的初始化方式(延迟初始化):

@H_404_1@

public static RoomsManager getRoomsManager(ServletContext servletContext) {
    if (servletContext.getAttribute(MANAGER_GAMES_ATTRIBUTE_NAME) == null) {
        servletContext.setAttribute(MANAGER_GAMES_ATTRIBUTE_NAME,new RoomsManager());
    }
    return (RoomsManager)servletContext.getAttribute(MANAGER_GAMES_ATTRIBUTE_NAME);
}
@H_404_1@并注释如下:

@H_404_1@

@WebListener
public class RoomsManager  implements ServletContextListener {
@H_404_1@停止按钮是intelij IDEA中播放和调试按钮附近的红色方块.
最佳答案
问题是你有两个不同的RoomsManager实例(因此有两个不同的执行器):第一个是由Tomcat创建的,第二个是由你创建的.

@H_404_1@当您使用@WebListener注释RoomsManager时,Tomcat会自动创建该类的实例并订阅它以接收servlet上下文创建/销毁事件.该实例是实际停止其执行程序并打印ServletContextListener的实例.

@H_404_1@第二个实例是由您在getRoomsManager方法中创建的(顺便说一下,该方法看起来不是线程安全的).该实例未在Tomcat中注册,并且未接收servlet上下文“destroy”事件,因此它甚至不会尝试关闭其执行程序.

猜你在找的Java相关文章