2009-03-17 15 views
5

Se implementa una aplicación web de fondo en un contenedor de servlet Tomcat 6. En la aplicación web, se inician varios hilos de supervisión. El problema es con el apagado.Cómo matar correctamente los hilos locales propiedad de una aplicación web que se ejecuta en tomcat con instrucciones de cierre

  • ¿Cómo sé que se solicita que la aplicación webapp se apague?
  • ¿Cómo debo manejar esto en mis hilos?

Actualmente mi hilo se implementa de la siguiente manera. Cuando se le indica al servlet que se apague (shutdown.sh), este completa un apagado limpio y no cuelga debido a este hilo. ¿Por qué?

class Updater extends Thread { 
    volatile boolean interrupted = false; 

    @Override 
    public void run() { 
    Integer lastUpdateLogId = CommonBeanFactory.getXXX() 
           .getLastUpdateLogRecordKey(MLConstants.SMART_DB_NAME); 

    List<UpdateLog> updateLogRecords; 
    while (!interrupted) { 
     boolean isConfigurationUpdateRequested = false; 

     try { 
     TimeUnit.SECONDS.sleep(5); 
     } catch (InterruptedException e) { 
     setInterrupted(true); 
     } 

     updateLogRecords = CommonBeanFactory.getXXX() 
         .getLastFactsUpdateLogRecords(MLConstants.XXXX, lastUpdateLogId); 

     for(UpdateLog updateLog : updateLogRecords) { 
     if (updateLog.getTable_name().equals(MLConstants.CONFIG_RELOAD)) { 
      isConfigurationUpdateRequested = true; 
     } 

     lastUpdateLogId = updateLog.getObjectKey(); 
     } 

     if (isConfigurationUpdateRequested) { 
     Configuration.getInstance().loadConfiguration(); 
     } 
    } 
    } 

    public boolean getInterrupted() { 
    return interrupted; 
    } 

    public void setInterrupted(boolean interrupted) { 
    this.interrupted = interrupted; 
    } 
} 

Respuesta

3

Los servlets reciben un evento del ciclo de vida cuando se les ordena que se apaguen. Puede usar este evento para detener su hilo de supervisión. Es decir, cuando se inicia un servlet, se llama a su método init(). Cuando se detiene, se llama a su método destroy().

Anule el método destroy() en su servlet y detenga el hilo allí.

Cuando llama al shutdown.sh se apaga la JVM completa. Como la JVM se detiene, todos los hilos (sin importar su estado) se detienen a la fuerza si aún se están ejecutando. Es el equivalente lógico de llamar a System.exit(0);

5

Creo que aún no puedo responder a las respuestas. La respuesta de Eddie no es del todo correcta.

Encontré esta pregunta porque estoy tratando de descubrir por qué mi aplicación web no se cierra correctamente; Tengo hilos que no mueren cuando cierro. *. De hecho, detiene algunos hilos pero finalmente se queda allí en algún estado de limbo. Mi clase es casi exactamente así, en realidad.

Al presionar Ctrl + C en primer plano, la ventana de Tomcat (en Windows) detiene todo, sin embargo, el uso del script de inicio que viene con Tomcat no lo hace. Desafortunadamente, todavía no entiendo por qué ...

Editar: Lo descubrí. La mayoría de mis subprocesos de supervisión se inician en un ServletContextListener, pero cuando ese contexto se "destruyó", los subprocesos secundarios no se notificaron. Lo arreglé simplemente manteniendo todos los hilos secundarios en una lista y dando vueltas, llamando a Thread.interrupt() en cada uno dentro del método contextDestroyed(). Es casi lo mismo que dijo Eddie sobre el método de servlet destroy().

Sin embargo, no es correcto que la JVM se cierre sumariamente cuando ejecuta shutdown. {Sh | bat}. Es más como que el script envía una solicitud de cierre a los componentes de Tomcat. Depende de usted recibir esos mensajes de cierre y pasarlos a sus propios objetos.

Cuestiones relacionadas