我知道我们不应该在servlet中启动线程,因为线程应该由容器管理。如果容器被告知关闭,如果有线程,它不知道挂在它周围不会关闭。我通过使它成为一个守护程序线程来处理这个......
但除了上面的“无法关闭”情况之外,还有什么其他原因可能不允许servlet启动线程。我看到有人提到,如果环境是聚集的,它将导致问题。但是,没有实际可能会发生的事情可能是不好的。
编辑: 目前这是在一个servlet中完成的,我很难说服这段代码的作者不是一个好主意。人们必须理解复杂性的论点是不会飞的...... 我正在寻找一个特定的具体案例,当一些不好的事情发生时,不打算
在我的情况下:有问题的servlet启动了n个线程,这种情况发生在集群上的每个vm中。 没有交易要求
答案 0 :(得分:2)
来自official FAQ:
为什么要创建和管理线程 不允许吗
EJB规范分配给 EJB容器的责任 管理线程。允许企业 用于创建和管理的bean实例 线程会干扰 容器控制它的能力 组件的生命周期。线 管理不是商业功能, 它是一个实现细节,而且是 通常很复杂 特定于平台的。让 容器管理线程减轻了 企业bean开发商的交易 有线程问题。多线程 应用程序仍然可行,但是 控制多线程的位置 在容器中,而不是在容器中 企业bean。
也就是说,如果不考虑启动和关闭的问题,那么从某种意义上说,线程是一个“哲学”问题,线程是实现细节,还有多线程的事实被视为可伸缩性关注点,应由应用管理。服务器。
例如,大多数应用程序。服务器允许集成商定义池并配置线程数等。生成线程的应用程序本身会逃避此配置,并且在可伸缩性计划中不能很好地协作。
此外,如果您希望在群集环境中使用单一后台主题,则会变得棘手。
最后,应用程序。服务器控制交易。如果您自己生成线程,则必须注意了解安全与否的所有详细信息(例如,从池中获取连接)以及如何在必要时使用UserTransaction
。我们的想法是,如果您使用应用程序,则不必担心此类细节。服务器,但是你需要自己开始处理线程。
然而,我看到网络应用程序从ServletContextListener
产生了一个后台线程,猜猜是什么,这很好,即使应用程序部署在多个节点上也是如此。您只需要了解运行多个JVM意味着什么,并确保您正确支持它。
答案 1 :(得分:1)
根据您的使用情况,存在很多问题。如果您的线程/作业正在运行的群集中的特定服务器崩溃,这会使您的线程消失,那会是一件坏事吗?是否应该通知某人?作业应该转移到群集中的另一台服务器吗?一旦服务器再次启动,它应该重新启动吗?所有这些,你必须在你的线程中实现....或者你可以使用JMS,它甚至可以在Tomcat中运行,使用ActiveMQ的插件,或者你选择的其他一些消息容器,然后编写代码执行你的逻辑,让容器担心所有其余的。 YMMV