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

发布于 2024-12-04 08:12:39 字数 188 浏览 0 评论 0原文

关于 Java EE 开发,我学到的第一件事就是我不应该在 Java EE 容器内生成自己的线程。但转念一想,我又不知道原因。

你能清楚地解释一下为什么不鼓励吗?

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

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

One of the first things I've learned about Java EE development is that I shouldn't spawn my own threads inside a Java EE container. But when I come to think about it, I don't know the reason.

Can you clearly explain why it is discouraged?

I am sure most enterprise applications need some kind of asynchronous jobs like mail daemons, idle sessions, cleanup jobs, etc.

So, if indeed one shouldn't spawn threads, what is the correct way to do it when needed?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

沦落红尘 2024-12-11 08:12:39

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

有多种方法可以“正确”地做到这一点,但这取决于所使用的平台。

commonj WorkManager 对于 WebSphere 和 WebLogic 以及其他应用程序来说是通用的

更多信息

这里

也有些重复这个 从今天早上

更新:请注意,这个问题和答案与状态有关2009 年 Java EE 发布后,情况有所改善!

It is discouraged because all resources within the environment are meant to be managed, and potentially monitored, by the server. Also, much of the context in which a thread is being used is typically attached to the thread of execution itself. If you simply start your own thread (which I believe some servers will not even allow), it cannot access other resources. What this means, is that you cannot get an InitialContext and do JNDI lookups to access other system resources such as JMS Connection Factories and Datasources.

There are ways to do this "correctly", but it is dependent on the platform being used.

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

More info here

And here

Also somewhat duplicates this one from this morning

UPDATE: Please note that this question and answer relate to the state of Java EE in 2009, things have improved since then!

樱花细雨 2024-12-11 08:12:39

对于 EJB,这不仅是不鼓励的,而且是 规范 明确禁止的:

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

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

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

For EJBs, it's not only discouraged, it's expressly forbidden by the specification:

An enterprise bean must not use thread
synchronization primitives to
synchronize execution of multiple
instances.

and

The enterprise bean must not attempt
to manage threads. The enterprise
bean must not attempt to start, stop,
suspend, or resume a thread, or to
change a thread’s priority or name.
The enterprise bean must not attempt
to manage thread groups.

The reason is that EJBs are meant to operate in a distributed environment. An EJB might be moved from one machine in a cluster to another. Threads (and sockets and other restricted facilities) are a significant barrier to this portability.

无法回应 2024-12-11 08:12:39

您不应该生成自己的线程的原因是这些线程不会由容器管理。容器处理了很多新手开发人员难以想象的事情。例如,线程池、集群、崩溃恢复等都是由容器执行的。当您启动一个线程时,您可能会丢失其中一些。此外,容器还允许您重新启动应用程序,而不会影响其运行的 JVM。如果存在容器无法控制的线程,这怎么可能?

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

The reason that you shouldn't spawn your own threads is that these won't be managed by the container. The container takes care of a lot of things that a novice developer can find hard to imagine. For example things like thread pooling, clustering, crash recoveries are performed by the container. When you start a thread you may lose some of those. Also the container lets you restart your application without affecting the JVM it runs on. How this would be possible if there are threads out of the container's control?

This the reason that from J2EE 1.4 timer services were introduced. See this article for details.

入画浅相思 2024-12-11 08:12:39

Java EE 的并发实用程序

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

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

示例此处

Concurrency Utilities for Java EE

There is now a standard, and correct way to create threads with the core Java EE API:

By using Concurrency Utils, you ensure that your new thread is created, and managed by the container, guaranteeing that all EE services are available.

Examples here

相守太难 2024-12-11 08:12:39

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

但要小心,bean 范围 sessionrequest 在生成的线程中不起作用!其他代码也基于 ThreadLocal 不能开箱即用,您需要自己将值传输到生成的线程。

There is no real reason not to do so. I used Quarz with Spring in a webapp without problems. Also the concurrency framework java.util.concurrent may be used. If you implement your own thread handling, set the theads to deamon or use a own deamon thread group for them so the container may unload your webapp any time.

But be careful, the bean scopes session and request do not work in threads spawned! Also other code beased on ThreadLocal does not work out of the box, you need to transfer the values to the spawned threads by yourself.

困倦 2024-12-11 08:12:39

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

遵守规则。有一天你会很高兴你这么做了:)

You can always tell the container to start stuff as part of your deployment descriptors. These can then do whatever maintainance tasks you need to do.

Follow the rules. You will be glad some day you did :)

风轻花落早 2024-12-11 08:12:39

根据蓝图,Java EE 容器中禁止使用线程。请参阅蓝图了解更多信息。

Threads are prohibited in Java EE containers according to the blueprints. Please refer to the blueprints for more information.

无人问我粥可暖 2024-12-11 08:12:39

我从来没有读到过有人不鼓励这样做,除了因为正确地做到这一点并不容易。

这是相当低级的编程,并且像其他低级技术一样,您应该有一个充分的理由。使用线程池等内置结构可以更有效地解决大多数并发问题。

I've never read that it's discouraged, except from the fact that it's not easy to do correctly.

It is fairly low-level programming, and like other low-level techniques you ought to have a good reason. Most concurrency problems can be resolved far more effectively using built-in constructs like thread pools.

谜兔 2024-12-11 08:12:39

我发现如果您在EJB中产生一些线程,然后尝试将容器卸载或更新EJB,您将遇到问题。几乎总是有另一种方法可以在不需要线程的地方做某事,所以只说不。

One reason I have found if you spawn some threads in you EJB and then you try to have the container unload or update your EJB you are going to run into problems. There is almost always another way to do something where you don't need a Thread so just say NO.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文