我有一个servlet S来处理来自第三方站点的回调。
回调调用按特定顺序发生。因此,我需要排队。
我建议使用像
这样的内存中队列java.util.ConcurrentLinkedQueue
所以逻辑看起来像这样:
据我所知,Servlet S的每个实例都在自己的Thread中执行。
如何为将为Queue提供服务的整个webapp(war)创建单个Consumer Thread?基本上我需要单例实例:
答案 0 :(得分:5)
这不是servlet容器的用途。如果您打算使用基于标准的方法,那么您真的需要一个更加完善的J2EE应用程序服务器。你将拥有的是其他黑客,但它们可能足以完成你的任务。
我可能会尝试创建一个DaemonServlet。这只是一个没有映射到URL的普通servlet(可能是用于监视目的的盲目URL,尽管更喜欢JMX用于此类事情)。加载servlet时会调用init()
方法。你可以在那里开始一个线程。可以说你可能需要创建两个:一个完成工作。另一个确保第一个正在运行,并在调用destroy()
后正常终止它。
或者,如果您正在使用Spring(并且,让我们面对它,什么样的whacko不使用Spring?),您可以简单地在应用程序上下文中创建一个大致相同的bean事情,除了Spring生命周期事件(例如InitializingBean上的afterPropertiesSet())。
实际上,我有一个更好的建议。使用asynchronous message consumers,这将更清晰,更具可扩展性,但这取决于基于JMS的解决方案,而不仅仅是LinkedBlockingQueue
(而且JMS可能是一个更好的主意) 。根据您的约束,您可能没有选择JMS作为选项。
答案 1 :(得分:2)
请记住,虽然您的servlet位于单独的线程中,但它们位于同一个VM实例中,因此它们位于共享内存空间中。如果您创建一个Singleton实例,它将自动由所有servlet共享。您还可以创建一个单独的servlet作为共享数据,这样做的好处是,如果需要,可以使用容器服务来保留它。
在OReilly关于servlet编程的书中,有一种彻底的检查方法 - 技术上称为“servlet协作” - 可在线获取here。
答案 2 :(得分:1)
哦,另一个想法:你不想做的一件事是尝试在servlet容器内管理你自己的线程池;它可以比你更好地进行线程池化,除非你弄乱它。
答案 3 :(得分:0)
我认为管理自己的线程池是一个坏主意。
Servlet用于处理HTTP请求。 HTTP是同步请求/响应协议。他们如何处理的逻辑属于其他地方。该处理程序可以是同步的或异步的,但应该由处理程序实现决定。 servlet应该决定为给定的响应推迟哪个处理程序,就是这样。
即使您使用Tomcat或servlet / JSP引擎,您仍然可以通过将ActiveMQ添加到Tomcat实现来使用Spring,JMS和MDP。
答案 4 :(得分:0)
使用侦听器,我创建了一个ThreadPool,可以使用ServletContext与旧版Tomcat应用程序集成,以存储ThreadPool并让侦听器管理生命周期,以免延误。
@WebListener
public class MyThreadPool implements ServletContextListener {
private static final String CONTEXT_ATTRIBUTE = "MyThreadPool";
private ExecutorService myThreadPool;
@Override
public void contextInitialized(ServletContextEvent sce) {
myThreadPool = Executors.newFixedThreadPool(10);
sce.getServletContext().setAttribute(CONTEXT_ATTRIBUTE, myThreadPool);
}
public static ExecutorService getPool(Servlet servlet) {
return (ExecutorService) servlet.getServletConfig()
.getServletContext().getAttribute(CONTEXT_ATTRIBUTE);
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
myThreadPool.shutdown();
sce.getServletContext().removeAttribute(CONTEXT_ATTRIBUTE);
}
}