2009-03-17 11 views
5

Eine Back-End-Webanwendung wird auf einem Tomcat 6-Servlet-Container bereitgestellt. In der Webapp werden mehrere Überwachungsthreads gestartet. Das Problem ist beim Herunterfahren.Wie Sie lokale Threads, die zu einer Webanwendung gehören, die auf dem Tomcat ausgeführt wird, ordnungsgemäß beenden müssen

  • Woher weiß ich, dass die Webanwendung zum Herunterfahren aufgefordert wird?
  • Wie soll ich das in meinen Threads behandeln?

Derzeit ist mein Thread wie folgt implementiert. Wenn das Servlet angewiesen wird, herunterzufahren (shutdown.sh), führt es einen sauberen Shutdown durch und hängt nicht wegen dieses Threads - Warum?

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

Antwort

3

Servlets erhalten ein Lebenszyklusereignis, wenn sie angewiesen werden, herunterzufahren. Sie können dieses Ereignis verwenden, um Ihren Überwachungs-Thread zu stoppen. Das heißt, wenn ein Servlet gestartet wird, wird seine init() Methode aufgerufen. Wenn es gestoppt wird, wird seine destroy() Methode aufgerufen.

Überschreiben Sie dieMethode in Ihrem Servlet und stoppen Sie den Thread dort.

Wenn Sie shutdown.sh aufrufen, wird die gesamte JVM heruntergefahren. Da die JVM gestoppt wird, werden alle Threads (unabhängig von ihrem Status) zwangsweise gestoppt, wenn sie noch ausgeführt werden. Es ist das logische Äquivalent zum Anruf System.exit(0);

5

Ich denke, ich kann Antworten noch nicht beantworten. Eddies Antwort ist nicht ganz korrekt.

Ich habe diese Frage gefunden, weil ich versuche herauszufinden, warum meine Webapp nicht richtig heruntergefahren wird; Ich habe Threads, die nicht getötet werden, wenn ich heruntergefahren. *. In der Tat, es stoppt einige Threads, aber letztlich sitzt nur dort in einigen Limbo-Zustand. Meine Klasse ist fast genau so wie diese.

Eingabe von Strg + C im Vordergrund Das Tomcat-Fenster (unter Windows) stoppt zwar alles, das Verwenden des mit Tomcat gelieferten Init-Skripts funktioniert jedoch nicht. Leider habe ich noch nicht herausgefunden warum ...

Edit: Ich habe es herausgefunden. Die meisten Überwachungs-Threads werden in einem ServletContextListener gestartet, aber wenn dieser Kontext "zerstört" wurde, wurden die untergeordneten Threads nicht benachrichtigt. Ich behob es, indem ich einfach alle untergeordneten Threads in einer Liste belassen und durchschleifen und Thread.interrupt() auf jedem innerhalb der contextDestroyed() -Methode aufrufen musste. Es ist fast das Gleiche wie das, was Eddie über die Methode desservlet destroy() gesagt hat.

Es ist jedoch nicht korrekt, dass die JVM beim Herunterfahren summarisch heruntergefahren wird. {Sh | bat}. Es ist eher so, dass das Skript eine Anforderung zum Herunterfahren an die Tomcat-Komponenten sendet. Es liegt an Ihnen, diese Shutdown-Nachrichten zu erhalten und sie an Ihre eigenen Objekte weiterzugeben.