我有一个处理特定传入请求的servlet。我们称之为“UpdateUserStats”。我希望呼叫速度快,但我还需要执行相当昂贵的任务。我认为,如果我让UpdateUserStats servlet执行所有确定成功或失败的工作,保持新状态,然后将一些工作排入后台线程以立即处理并立即返回成功,那么这可能是一个很好的解决方案。 / p>
这看起来不错,但我想知道如何处理关机。当服务器关闭时,我想确保它不会杀死后台线程,直到不再有工作。我正在考虑使用tomcat ServletContextListener让后台线程知道服务器正在关闭,一旦队列结束就可以退出,但我不能100%确定这将如何表现。只有在完成所有请求处理后才会contextDestroyed()
吗?界面似乎暗示了这一点,但我没有在文档中找到它。另外,我想知道Tomcat在生气背景线程没有终止之前愿意等待多久。
或者,有没有更好的方法来处理这个问题?如果Spring有一些神奇的后期请求后台工作功能,那么这是一个Spring应用程序。
答案 0 :(得分:1)
提到替代方案,您可以在单独的JVM中创建队列(使用ActiveMQ,RabbitMQ或更简单的东西)。这样,即使tomcat出现故障,也会处理一旦排队的任务。
答案 1 :(得分:1)
您可以在应用程序范围内使用最多没有线程的ThreadPool,然后它将在必要时排队并能够根据硬件和线程任务进行配置。为此,您需要使用ExecutorService:http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html
ThreadPool可以初始化如下
executorPool = Executors.newFixedThreadPool(50);
在您的服务方法中,您可以定义提交到线程,如下所示: executorPool.submit(new ProcessTask());
清理ThreadPool可以在销毁/关闭期间完成(应用程序) executorPool.shutdownNow();
希望这有用
答案 2 :(得分:1)
基于servlet规范文档
“在应用程序关闭时,将以与其声明相反的顺序通知侦听器 向会话侦听器发出通知,然后通知上下文侦听器。 必须在上下文侦听器之前通知会话侦听器会话失效 被通知应用程序关闭。“
所以这应该是第一个处理通知线程完成其工作的监听器。
我已经使用了tomcat,就我所看到的情况而言,如果听众没有完成,那么在放弃干净关闭之前,它不会等待超过10-15秒。
通常,像Spring这样的所有容器都会在关闭期间使用侦听器进行干净的退出