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

问题

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

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

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

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


#1 热门回答(81 赞)

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

有很多方法可以"正确"执行此操作,但这取决于所使用的平台。
The commonj WorkManager is common for WebSphere and WebLogic as well as othersMore info hereAnd here
从今天早上起也有点重复this one

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


#2 热门回答(32 赞)

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

企业bean不得使用线程同步原语来同步多个实例的执行。

企业bean不得尝试管理线程。企业bean不得尝试启动,停止,挂起或恢复线程,也不得尝试更改线程的优先级或名称。企业bean不得尝试管理线程组。

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


#3 热门回答(12 赞)

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

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