为什么不鼓励在Java EE容器中生成线程?

时间:2009-02-10 19:25:14

标签: java multithreading java-ee

我学到的关于Java EE开发的第一件事就是我不应该在Java EE容器中生成我自己的线程。但是当我开始思考它时,我不知道原因。

你能清楚地解释为什么气馁吗?

我相信大多数企业应用程序都需要某种异步工作,如邮件守护进程,空闲会话,清理工作等。

因此,如果确实不应该生成线程,那么在需要时执行它的正确方法是什么?

9 个答案:

答案 0 :(得分:84)

不鼓励这样做,因为服务器要管理并可能监视环境中的所有资源。此外,正在使用线程的大部分上下文通常附加到执行线程本身。如果您只是启动自己的线程(我相信某些服务器甚至不允许),它就无法访问其他资源。这意味着,您无法获取InitialContext并执行JNDI查找以访问其他系统资源,例如JMS连接工厂和数据源。

有很多方法可以“正确”执行此操作,但这取决于所使用的平台。

The commonj WorkManager is common for WebSphere and WebLogic as well as others

More info here

And here

从今天早上开始有点重复this one

更新:请注意,这个问题和答案与2009年的Java EE状态有关,从那时起情况有所改善!

答案 1 :(得分:33)

对于EJB,它不仅气馁,而且明确禁止specification

  

企业bean不能使用线程   同步原语到   同步多个执行   实例

  

企业bean不得尝试   管理线程。企业   bean不能试图启动,停止,   暂停,或恢复一个线程,或   更改线程的优先级或名称。   企业bean不得尝试   管理线程组。

原因是EJB旨在在分布式环境中运行。 EJB可能会从群集中的一台计算机移动到另一台计算机。线程(以及套接字和其他受限设施)是这种可移植性的重大障碍。

答案 2 :(得分:12)

您不应该生成自己的线程的原因是容器不会管理这些线程。容器会处理很多新手开发人员难以想象的事情。例如,容器执行线程池,群集,崩溃恢复等操作。当你开始一个线程时,你可能会失去一些。此外,容器还允许您重新启动应用程序,而不会影响它运行的JVM。如果容器的控件中有线程,这怎么可能呢?

这就是引入J2EE 1.4计时器服务的原因。有关详细信息,请参阅this文章。

答案 3 :(得分:7)

Java EE的并发实用程序

现在有一种使用核心Java EE API创建线程的标准且正确的方法:

通过使用Concurrency Utils,您可以确保创建新线程并由容器管理,从而保证所有EE服务都可用。

示例here

答案 4 :(得分:2)

没有真正的理由不这样做。我在webapp中使用QuarzSpring没有问题。也可以使用并发框架java.util.concurrent。如果您实现自己的线程处理,请将theads设置为deamon或使用自己的deamon线程组,以便容器可以随时卸载您的webapp。

但是要小心,bean范围 session request 在生成的线程中不起作用!另外,ThreadLocal上的其他代码无法开箱即用,您需要自己将值传递给生成的线程。

答案 5 :(得分:2)

您始终可以告诉容器启动内容作为部署描述符的一部分。然后,这些可以执行您需要执行的任何维护任务。

遵守规则。有一天你会很高兴:)

答案 6 :(得分:2)

根据蓝图,Java EE容器中禁止使用线程。有关详细信息,请参阅blueprints

答案 7 :(得分:1)

我从来没有读到这是沮丧的,除非事实并非如此。

这是相当低级的编程,和其他低级技术一样,你应该有充分的理由。使用内置构造(如线程池)可以更有效地解决大多数并发问题。

答案 8 :(得分:1)

我发现如果你在EJB中生成一些线程然后你试图让容器卸载或更新你的EJB会遇到问题的一个原因。几乎总有另一种方法可以做一些你不需要线程的事情,所以只说不。