Why is spawning threads in Java EE container discouraged?
Asked Answered
W

9

126

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?

Watusi answered 10/2, 2009 at 19:25 Comment(4)
Asynchronous tasks are usually done using JMS messaging and MDBs.Enthusiast
This issue should soon be a thing of the past once JSR 236 is implemented in the containers.Preponderant
It was discouraged because any second threads should be created and managed by the container, so that the thread will have access to the other enterprise resources. With Java EE7, there is a standard, and correct way to create threads in an enterprise environment. By using Concurrency Utils, you ensure that your new thread is created, and managed by the container, guaranteeing that all EE services are available. Example hereAuditorium
Several correct ways in JSF/EJB perspective can be found here: https://mcmap.net/q/18471/-is-it-safe-to-manually-start-a-new-thread-in-java-eeArithmetic
M
85

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!

Monies answered 10/2, 2009 at 19:43 Comment(4)
you cannot get an InitialContext and do JNDI lookups to access other system resources such as JMS Connection Factories and Datasources. I have an app that works around this by injecting the datasource when starting the threads, but I might have to rethink this approach...Generable
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 and hereAuditorium
@ChrisRitchie thanks for the tip. if only JBoss AS/IBM WAS supported Java EE 7... :-(Scurlock
@Scurlock WildFly 8 (new name for JBoss AS) does support Java EE 7. IBM is only Java EE 6 certified certificationAuditorium
O
34

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.

Osteen answered 10/2, 2009 at 23:6 Comment(2)
Java EE7 Concurrency Utils provide a correct way to create threads in an enterprise environment. Examples here and hereAuditorium
@Dan Can you explain to me why a Thread would be significant barrier to the portability of moving an EJB from one machine in a custer to another?Ski
O
13

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.

Oakleil answered 10/2, 2009 at 19:39 Comment(1)
JSR 236 added features to support spawning threads in Java EE 7 and later. See this sibling Answer by Chris Ritchie.Parted
A
12

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

Auditorium answered 16/10, 2013 at 13:14 Comment(0)
A
3

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.

Abraxas answered 10/2, 2009 at 19:48 Comment(0)
A
2

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 :)

Adessive answered 10/2, 2009 at 19:56 Comment(0)
C
2

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

Culmiferous answered 23/12, 2010 at 10:55 Comment(0)
F
1

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.

Forgather answered 10/2, 2009 at 19:28 Comment(1)
it is indeed forbidden by the spec.Enthusiast
H
1

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.

Horologist answered 10/2, 2009 at 22:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.