【问题标题】:Java, Tomcat, ServletContextListener, and a background threadJava、Tomcat、ServletContextListener 和后台线程
【发布时间】:2011-08-09 21:56:49
【问题描述】:

我有一个处理特定传入请求的 servlet。我们称它为“UpdateUserStats”。我希望调用速度很快,但我也需要请求来完成一项相当昂贵的任务。我认为如果让 UpdateUserStats servlet 完成所有决定成功或失败的工作,保持新状态,然后将一些工作排​​入队列以供后台线程处理并立即返回成功,我认为这可能是一个不错的解决方案。

这看起来不错,但我想知道如何处理关机。当服务器关闭时,我想确保它不会杀死后台线程,直到没有更多的工作。我正在考虑使用 tomcat ServletContextListener 让后台线程知道服务器正在关闭,一旦队列结束就可以退出,但我不能 100% 确定这将如何表现。只有在处理完所有请求之后,contextDestroyed() 才会?界面似乎暗示了这一点,但我没有在文档中找到它。另外,我想知道 Tomcat 愿意等待多长时间才会因为后台线程没有终止而生气。

或者,有没有更好的方法来处理这个问题?如果 Spring 有一些神奇的请求后后台工作功能,它就是一个 Spring 应用程序。

【问题讨论】:

    标签: java tomcat servlets spring-mvc


    【解决方案1】:

    基于 servlet 规范文档

    “在应用程序关闭时,会以与声明相反的顺序通知侦听器 向会话侦听器发出通知,然后再向上下文侦听器发出通知。 会话侦听器必须在上下文侦听器之前通知会话失效 收到应用程序关闭的通知。”

    所以这应该是第一个处理通知线程完成其工作的侦听器。

    我使用过tomcat,据我所知,如果监听器到那时还没有完成,它不会等待超过10-15秒就放弃彻底关闭。

    通常所有容器(如 Spring)在关闭期间使用侦听器进行干净退出

    【讨论】:

      【解决方案2】:

      提到替代方案,您可以在单独的 JVM 中创建队列(使用 ActiveMQ、RabbitMQ 或更简单的东西)。这样,即使tomcat宕机,任务一旦入队也会被处理。

      【讨论】:

        【解决方案3】:

        您可以在应用程序范围内使用最大线程数的 ThreadPool,然后它会在必要时排队,并且能够根据硬件和线程任务进行配置。为此,您需要使用 ExecutorService :http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html

        ThreadPool 可以如下初始化

        executorPool = Executors.newFixedThreadPool(50);

        在您的服务方法中,您可以定义提交到线程,如下所示: executorPool.submit(new ProcessTask());

        在销毁/关闭(应用程序)期间,可以按如下方式清理线程池 executorPool.shutdownNow();

        希望对你有帮助

        【讨论】:

          猜你喜欢
          • 2016-03-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-11-29
          • 1970-01-01
          • 2010-10-21
          相关资源
          最近更新 更多