我们正在创建一个Web应用程序,我们需要为一些业务案例提供并发性。此应用程序将部署在tomcat容器中。我知道在Web容器中创建用户定义的线程是个坏主意,我正在尝试探索我拥有的选项。
对此有任何帮助表示赞赏。顺便说一句,由于部署环境,使用JMS是不可能的。我倾向于第3点和第4点,但我对此并不了解。有人可以指导。
答案 0 :(得分:4)
由于你正在使用Tomcat,所以不要担心它并做任何你想做的事情。 Java EE的Servlet部分没有提到线程等。这主要是在EJB部分。
在担心管理线程方面,Tomcat本身并没有做太多的事情,它是一个非常非侵入性的容器。
最好将你的线程绑定到ServletContextListener,以便你可以关注应用程序生命周期,并在应用程序关闭时关闭你的东西,但除此之外,不要过分关注它并使用你所做的任何事情。很高兴。
补遗 -
简单的事实是Tomcat并不关心,而且它并不那么复杂。 Tomcat为每个HTTP侦听器都有一个线程池,这是关于它的管理级别的结束。例如,Tomcat不会从安静的HTTP侦听器中获取线程并将它们专用于繁忙的HTTP侦听器。如果Tomcat真的对你如何创建线程感兴趣,它会阻止你这样做 - 而事实并非如此。
这意味着HTTP上下文之外的线程管理完全落在您的肩上作为实现者。 Java EE公开了这些类型的工具,接口可以实现很好的读取。但简单的事实是,Java EE API文档所支持的理论能力,以及现代实现的现实情况大不相同,特别是在Tomcat等低端系统上。
不要贬低Tomcat。 Tomcat是一款非常棒的软件。但对于大多数用例而言,额外的管理功能根本不是必需的。
设置您自己的线程池(使用JDK提供的工具)并使用您自己的线程生命周期模型可能会成功通过您正在处理的任何项目。这真的不是什么大不了的事。
答案 1 :(得分:1)
有几种选择。无论可能存在还是可能没有的容器限制,按需生成单个线程几乎总是一个坏主意。并不是说这在Servlet环境中不起作用,但是你可能创建的线程数可能会完全失控。
最简单的解决方案是通过普通的执行器服务提供一个普通的旧Java SE线程池。在Servlet侦听器中启动池,并通过一些静态变量提供对它的访问。不是太漂亮,但它完成了工作。根据您的确切用例,这实际上可能是最佳解决方案(如果您的用例非常低级)。
另一个选择是在战争中添加OpenEJB,然后利用@Asynchronous注释。
另一个选择是,如果业务需求极其简单或低级别,则通常会使用Tomcat。这就是使用Tomcat作为裸骨的东西的全部意义。一旦你发现自己需要添加(吨)库,你可能已经超出了Tomcat,并且可能更好地使用已经具有所需功能的服务器(在这种情况下是异步执行)。例如TomEE,GlassFish,Resin,JBoss AS,Geronimo等。
答案 2 :(得分:0)
Web应用程序中用于HTTP请求处理的每个Servlet -Java EE基本组件都是Singleton,每个请求都在其自己的独立线程中运行,因此无需自己启动/停止用户生成的线程。您的Web容器 - 在这种情况下Tomcat-管理所有这些东西。
除此之外,您还需要考虑代码中多线程处理的一些注意事项。例如,由于Servlet是单例,并且为这个类生成了许多线程,因此在这个组件中拥有实例属性是个坏主意。
答案 3 :(得分:0)
我多次使用过CommonJ,效果很好。它可以从ServletContextListener初始化和销毁。