当前位置: 首页 > 知识库问答 >
问题:

停止Tomcat时ExecutorService不会从contextDestroyed()关闭

柳珂
2023-03-14

我有一个类,实现ServletContextListener,并用@WebListener注释它。

我在该类中有两个方法:

@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");
}

我看到,当它应该打印它们中的内容时,它会打印出来,但当我在intelij中按一次停止按钮时,我会得到:

我需要再按一次停止按钮才能完全停止。

为什么即使到达executor.shutdown();也不关闭ExecutorService?我做错了什么?

PS:这是我唯一的ExecutorService,没有其他线程是我做的。

private ExecutorService executor = Executors.newSingleThreadExecutor();
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);
}
@WebListener
public class RoomsManager  implements ServletContextListener {

停止按钮是intelij IDEA中play和debug按钮附近的红色方块。

共有1个答案

司马庆
2023-03-14

问题是您有两个不同的RoomsManager实例(因此有两个不同的执行者):第一个由Tomcat创建,第二个由您创建。

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

第二个实例是在getRoomsManager方法中创建的(顺便说一下,该方法看起来不是线程安全的)。该实例没有向Tomcat注册,也不会接收servlet上下文“destroy”事件,因此它甚至不会尝试关闭其执行器。

 类似资料:
  • 问题内容: 我可以使用成功启动,文档中提到可以正常退出应用程序hit ctrl-c。 Maven进程确实终止了,但是Tomcat仍在运行,我仍然可以访问该网页。当我再次尝试启动spring-boot时,由于端口正在使用中,因此无法启动Tomcat。 要继续,我必须手动终止正在运行的进程。这是一个错误还是我错过了什么? 问题答案: 我仍然在Windows 7上运行的1.1.9版本上碰巧。 因此,在按

  • 要继续,我必须手动终止正在运行的进程。这是一个窃听器还是我遗漏了什么?

  • 问题内容: 我已将一个WAR文件部署到Tomcat服务器,该类之一将在启动时调用,然后init()方法将安排一个计时器,每5小时触发一次以执行一些任务。 我的init()代码如下所示: 我的应用程序运行没有问题,但是当我使用 /etc/init.d/tomcat7 stop 关闭Tomcat时,我检查了日志(catalina.out),它具有以下条目: 严重:Web应用程序[/ MyApplica

  • 问题内容: 我有一个在Linux中运行的操作系统,可以通过 来启动和关闭 除了1个问题,其他都还可以。有时tomcat不会停止。 尽管我停止了它,并且在catalina.out日志中看到了正在下降的日志,但是如果我这样做,仍然可以看到该进程正在运行。 可能是什么问题呢?我该如何调试?我的感觉是,这与线程有关。 因此,以下是可疑部分: 1)我使用Log4j的LogManager来检测log4j配置是

  • 问题内容: 我正在尝试使用Linux下的ProcessBuilder类将mp3文件解码为wav文件。由于某些原因,该过程不会停止,因此我必须手动取消它。 有人可以给我一个提示。我认为引用的代码很容易重现: jstack的输出 问题答案: 您需要清空进程的输出(通过)和错误(通过)流,否则可能会阻塞。 引用过程文档: 由于某些本机平台仅为标准输入和输出流提供有限的缓冲区大小,因此未能及时写入子流程的

  • 我通过创建固定数量的线程来使用执行器服务来进行HTTP GET数据检索。 当Tomcat停止时,我们会出现以下错误: 严重:web应用程序[/viewer]似乎已启动名为[ThreadExecutor_51616156]的线程,但未能停止该线程。这很可能会造成内存泄漏。 这是真的吗?在没有这些服务错误的情况下,如何正确停止tomcat。