¿Por qué se desaconseja la generación de subprocesos en el contenedor Java EE?

120

Una de las primeras cosas que aprendí sobre el desarrollo de Java EE es que no debería generar mis propios hilos dentro de un contenedor Java EE. Pero cuando lo pienso, no sé la razón.

¿Puede explicar claramente por qué se desaconseja?

Estoy seguro de que la mayoría de las aplicaciones empresariales necesitan algún tipo de trabajos asincrónicos como demonios de correo, sesiones inactivas, trabajos de limpieza, etc.

Entonces, si de hecho uno no debería generar hilos, ¿cuál es la forma correcta de hacerlo cuando sea necesario?

LiorH
fuente
4
Las tareas asincrónicas se realizan normalmente mediante mensajería JMS y MDB.
Ken Liu
5
Este problema pronto debería ser cosa del pasado una vez que JSR 236 se implemente en los contenedores.
letmaik
5
Que se desanime porque cualquier segundos hilos deben ser creados y gestionados por el contenedor, por lo que el hilo tendrá acceso a los demás recursos de la empresa. Con Java EE7, existe una forma estándar y correcta de crear subprocesos en un entorno empresarial. Al utilizar Concurrency Utils, se asegura de que su nuevo hilo sea creado y administrado por el contenedor, lo que garantiza que todos los servicios de EE estén disponibles. Ejemplo aquí
Chris Ritchie
Se pueden encontrar varias formas correctas en la perspectiva JSF / EJB aquí: stackoverflow.com/q/6149919
BalusC

Respuestas:

84

Se desaconseja porque todos los recursos del entorno están destinados a ser administrados y potencialmente monitoreados por el servidor. Además, gran parte del contexto en el que se utiliza un hilo se adjunta normalmente al hilo de ejecución en sí. Si simplemente inicia su propio hilo (que creo que algunos servidores ni siquiera permitirán), no podrá acceder a otros recursos. Lo que esto significa es que no puede obtener un InitialContext y realizar búsquedas JNDI para acceder a otros recursos del sistema, como JMS Connection Factories y Datasources.

Hay formas de hacer esto "correctamente", pero depende de la plataforma que se utilice.

Commonj WorkManager es común para WebSphere y WebLogic, así como para otros

Más info aquí

Y aquí

También algo duplica este de esta mañana.

ACTUALIZACIÓN: Tenga en cuenta que esta pregunta y respuesta se relacionan con el estado de Java EE en 2009, ¡las cosas han mejorado desde entonces!

Robin
fuente
1
no puede obtener un InitialContext y realizar búsquedas JNDI para acceder a otros recursos del sistema, como JMS Connection Factories y Datasources. Tengo una aplicación que
soluciona
6
Ahora existe una forma estándar y correcta de crear subprocesos con la API principal de Java EE. Al utilizar Concurrency Utils, se asegura de que su nuevo hilo sea creado y administrado por el contenedor, lo que garantiza que todos los servicios de EE estén disponibles. Ejemplos aquí y aquí
Chris Ritchie
@ChrisRitchie gracias por el dato. si solo JBoss AS / IBM FUE compatible con Java EE 7 ... :-(
asgs
1
@asgs WildFly 8 (nuevo nombre para JBoss AS) admite Java EE 7. IBM solo tiene certificación certificada
Chris Ritchie
34

Para los EJB, no solo se desalienta, sino que está expresamente prohibido por la especificación :

Un enterprise bean no debe utilizar primitivas de sincronización de subprocesos para sincronizar la ejecución de varias instancias.

y

El enterprise bean no debe intentar gestionar subprocesos. El enterprise bean no debe intentar iniciar, detener, suspender o reanudar un hilo, ni cambiar la prioridad o el nombre de un hilo. El enterprise bean no debe intentar gestionar grupos de hebras.

La razón es que los EJB están diseñados para funcionar en un entorno distribuido. Un EJB se puede mover de una máquina en un clúster a otra. Los hilos (y los enchufes y otras instalaciones restringidas) son una barrera importante para esta portabilidad.

Dan Dyer
fuente
3
Las utilidades de concurrencia Java EE7 proporcionan una forma correcta de crear subprocesos en un entorno empresarial. Ejemplos aquí y aquí
Chris Ritchie
1
@Dan ¿Puede explicarme por qué un Thread sería una barrera importante para la portabilidad de mover un EJB de una máquina en un custer a otra?
Geek
13

La razón por la que no debe generar sus propios hilos es que el contenedor no los administrará. El contenedor se encarga de muchas cosas que un desarrollador novato puede encontrar difíciles de imaginar. Por ejemplo, el contenedor realiza cosas como la agrupación de subprocesos, la agrupación en clústeres y las recuperaciones de fallos. Cuando comienzas un hilo, puedes perder algunos de ellos. Además, el contenedor le permite reiniciar su aplicación sin afectar la JVM en la que se ejecuta. ¿Cómo sería esto posible si hay subprocesos fuera del control del contenedor?

Esta es la razón por la que a partir de J2EE 1.4 se introdujeron los servicios de temporizador. Consulte este artículo para obtener más detalles.

kgiannakakis
fuente
2
JSR 236 agregó características para admitir hilos de generación en Java EE 7 y versiones posteriores. Vea la respuesta de este hermano de Chris Ritchie .
Basil Bourque
8

Utilidades de simultaneidad para Java EE

Ahora existe una forma estándar y correcta de crear subprocesos con la API principal de Java EE:

Al utilizar Concurrency Utils, se asegura de que su nuevo hilo sea creado y administrado por el contenedor, lo que garantiza que todos los servicios de EE estén disponibles.

Ejemplos aquí

Chris Ritchie
fuente
2

Siempre puede decirle al contenedor que comience cosas como parte de sus descriptores de implementación. Luego, estos pueden realizar las tareas de mantenimiento que necesite realizar.

Sigue las reglas. Te alegrarás algún día de haberlo hecho :)

Thorbjørn Ravn Andersen
fuente
2

Los subprocesos están prohibidos en los contenedores Java EE de acuerdo con los planos. Consulte los planos para obtener más información.

Ojitha
fuente
2

No hay ninguna razón real para no hacerlo. Solía Quarz con la primavera en una aplicación web sin problemas. También java.util.concurrentse puede utilizar el marco de concurrencia . Si implementa su propio manejo de subprocesos, configure los theads en demonio o use un grupo de subprocesos deamon para ellos para que el contenedor pueda descargar su aplicación web en cualquier momento.

Pero tenga cuidado, la sesión y la solicitud de los alcances de bean no funcionan en los subprocesos generados. Además, otro código basado en ThreadLocalno funciona de inmediato, debe transferir los valores a los subprocesos generados usted mismo.

Arne Burmeister
fuente
1

Nunca he leído que esté desanimado, excepto por el hecho de que no es fácil hacerlo correctamente.

Es una programación de nivel bastante bajo y, al igual que otras técnicas de bajo nivel, debería tener una buena razón. La mayoría de los problemas de simultaneidad se pueden resolver de manera mucho más efectiva utilizando construcciones integradas como grupos de subprocesos.

levand
fuente
7
de hecho, está prohibido por la especificación.
Ken Liu
1

Una razón por la que he descubierto que si genera algunos subprocesos en su EJB y luego intenta que el contenedor se descargue o actualice su EJB, tendrá problemas. Casi siempre hay otra forma de hacer algo en lo que no necesitas un hilo, así que di NO.

Javamann
fuente