Why is spawning threads in Java EE container discouraged?

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.


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.


Concurrency Utilities for Java EE

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

  • JSR 236: Concurrency Utilities for Java™ EE

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


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!