¿Por qué se desalientan los hilos de desove en el contenedor Java EE?

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.

¿Puedes explicar claramente por qué está desaconsejado?

Estoy seguro de que la mayoría de las aplicaciones empresariales necesitan algún tipo de trabajos asíncronos como daemons de correo, sesiones inactivas, trabajos de limpieza, etc.

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

Se desaconseja porque el servidor debe gestionar y controlar potencialmente todos los recursos del entorno. Además, gran parte del contexto en el que se utiliza un subproceso generalmente se adjunta al subproceso de ejecución en sí. Si simplemente inicia su propio hilo (que creo que algunos servidores ni siquiera permitirán), no puede 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, tales como Fábricas de conexiones JMS y Fuentes de datos.

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 información aquí

Y aquí

También algo duplica este de esta mañana

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

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

Un enterprise bean no debe usar primitivas de sincronización de subprocesos para sincronizar la ejecución de instancias múltiples.

y

Enterprise Bean no debe intentar administrar los hilos. Enterprise Bean no debe intentar iniciar, detener, suspender o reanudar un hilo o cambiar la prioridad o el nombre de un hilo. Enterprise Bean no debe intentar administrar grupos de subprocesos.

La razón es que los EJB están destinados a operar en un entorno distribuido. Un EJB puede moverse de una máquina en un clúster a otro. Los hilos (y los sockets y otras instalaciones restringidas) son una barrera significativa a esta portabilidad.

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

Este es el motivo por el que se introdujeron los servicios del temporizador J2EE 1.4. Ver este artículo para más detalles.

Utilidades de simultaneidad para Java EE

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

  • JSR 236: Utilidades de Concurrencia para Java ™ EE

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

Ejemplos aquí

Siempre puede decirle al contenedor que inicie cosas como parte de los descriptores de implementación. Estos pueden hacer las tareas de mantenimiento que necesites hacer.

Sigue las reglas. Estarás contento algún día lo hiciste 🙂

Los hilos están prohibidos en contenedores Java EE de acuerdo con los planos. Por favor refiérase a los planos para más información.

No hay una razón real para no hacerlo. Utilicé Quarz con Spring en una aplicación web sin problemas. También se puede usar el marco de simultaneidad java.util.concurrent . Si implementa su propio manejo de subprocesos, configure theads para deamon o use un grupo de subprocesos propio deamon para que el contenedor pueda descargar su aplicación web en cualquier momento.

¡Pero tenga cuidado, la sesión de los ámbitos de frijol y la solicitud no funcionan en hilos generados! Además, el otro código ThreadLocal en ThreadLocal no funciona de la caja, usted necesita transferir los valores a los hilos engendrados por usted mismo.

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

Es una progtwigción de bajo nivel y, como otras técnicas de bajo nivel, deberías tener una buena razón. La mayoría de los problemas de concurrencia se pueden resolver de forma mucho más efectiva utilizando construcciones integradas como grupos de subprocesos.

Una razón que he encontrado si engendras algunos hilos en tu EJB y luego tratas de que el contenedor descargue o actualice tu EJB te va a dar problemas. Casi siempre hay otra manera de hacer algo que no necesita un hilo, así que solo diga NO.