¿Por qué no se recomienda generar subprocesos 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 de Java EE. Pero cuando lo pienso, no sé el motivo.
¿Puedes explicar claramente por qué se desaconseja?
Estoy seguro de que la mayoría de las aplicaciones empresariales necesitan algún tipo de trabajo asincrónico, como demonios de correo, sesiones inactivas, trabajos de limpieza, etc.
Entonces, si realmente no se deberían generar subprocesos, ¿cuál es la forma correcta de hacerlo cuando sea necesario?
Se desaconseja porque todos los recursos dentro del entorno deben ser administrados y potencialmente monitoreados por el servidor. Además, gran parte del contexto en el que se utiliza un subproceso suele estar vinculado al propio subproceso de ejecución. Si simplemente inicia su propio hilo (lo que creo que algunos servidores ni siquiera permiten), 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.
El commonj WorkManager es común para WebSphere y WebLogic, así como para otros.
Más información aquí
Y aquí
También duplica un poco 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!
Para los EJB, no solo no se recomienda, sino que la especificación lo prohíbe expresamente :
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 subproceso, ni cambiar la prioridad o el nombre de un subproceso. El Enterprise Bean no debe intentar gestionar grupos de subprocesos.
La razón es que los EJB están destinados a operar en un entorno distribuido. Un EJB se puede mover de una máquina de un clúster a otra. Los hilos (y los enchufes y otras instalaciones restringidas) son una barrera importante para esta portabilidad.
La razón por la que no debes generar tus propios hilos es que el contenedor no los administrará. El contenedor se encarga de muchas cosas que a un desarrollador novato le resultaría difícil imaginar. Por ejemplo, el contenedor realiza cosas como la agrupación de subprocesos, la agrupación en clústeres y la recuperación de fallos. Cuando inicias un hilo, es posible que pierdas 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.
Utilidades de concurrencia 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 simultaneidad para Java™ EE
Al utilizar Concurrency Utils, se asegura de que el contenedor cree y administre su nuevo subproceso, lo que garantiza que todos los servicios EE estén disponibles.
Ejemplos aquí
No existe ninguna razón real para no hacerlo. Usé Quarz con Spring en una aplicación web sin problemas. java.util.concurrent
También se puede utilizar el marco de concurrencia . Si implementa su propio manejo de subprocesos, configure los theads en demonio o use un grupo de subprocesos demoníaco propio para ellos, de modo que el contenedor pueda descargar su aplicación web en cualquier momento.
¡Pero tenga cuidado, la sesión y la solicitud de alcances de beans no funcionan en los subprocesos generados! Además, otro código basado en ThreadLocal
no funciona de inmediato, debe transferir los valores a los subprocesos generados usted mismo.