2009-03-17 4 views
5

Una webapp backend viene distribuita su un contenitore di servlet Tomcat 6. Nella webapp vengono avviati diversi thread di monitoraggio. Il problema è con l'arresto.Come eliminare correttamente i thread locali di proprietà di una webapp in esecuzione su tomcat con istruzioni per lo spegnimento

  • Come faccio a sapere che la webapp è richiesta per l'arresto?
  • Come devo gestirlo nei miei thread?

Attualmente il mio thread è implementato come di seguito. Quando il servlet viene istruito su shutdown (shutdown.sh) completa un arresto pulito e non si blocca a causa di questo thread - Perché?

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; 
    } 
} 

risposta

3

I servlet ricevono un evento del ciclo di vita quando viene richiesto di spegnersi. È possibile utilizzare questo evento per interrompere il thread di monitoraggio. Cioè, quando viene avviato un servlet, viene chiamato il suo metodo init(). Quando viene arrestato, viene chiamato il suo metodo destroy().

Ignora il metodo destroy() nel servlet e interrompi il thread.

Quando si chiama shutdown.sh l'intera JVM viene chiusa. Poiché la JVM si arresta, tutti i thread (indipendentemente dal loro stato) vengono fermati forzatamente se ancora in esecuzione. È l'equivalente logico di chiamare System.exit(0);

5

Credo di non poter ancora rispondere alle risposte. La risposta di Eddie non è del tutto corretta.

Ho trovato questa domanda perché sto cercando di capire perché la mia webapp non si spegne correttamente; Ho thread che non vengono uccisi quando corro shutdown. *. In effetti, interrompe alcuni thread ma alla fine rimane solo in uno stato limbo. La mia classe è quasi esattamente come questa, in realtà.

Digitando Ctrl + C nella finestra di primo piano Tomcat (su Windows) interrompe tutto, tuttavia non utilizza lo script di inizializzazione fornito con Tomcat. Purtroppo, non ho ancora capito perché ...

Modifica: l'ho capito. La maggior parte dei miei thread di monitoraggio sono avviati in un ServletContextListener, ma quando tale contesto è stato "distrutto", i thread secondari non sono stati notificati. Ho risolto il problema semplicemente mantenendo tutti i thread figlio in un elenco e eseguendo il looping, chiamando Thread.interrupt() su ognuno nel metodo contextDestroyed(). È quasi la stessa cosa che ha detto Eddie a proposito del metodo servlet destroy().

Tuttavia, non è corretto che la JVM venga arrestata in modo sommario quando si esegue l'arresto. {Sh | bat}. È più simile a quello script che invia una richiesta di arresto ai componenti Tomcat. Sta a te ricevere quei messaggi di spegnimento e trasmetterli ai tuoi stessi oggetti.

Problemi correlati