2017-11-18 14 views
2

Nehmen wir an, wir solch eine triviale Daemon in Java geschrieben haben:Wie verarbeitet man das SIGTERM-Signal elegant in Java?

public class Hellow { 
    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 
     while(true) { 
      // 1. do 
      // 2. some 
      // 3. important 
      // 4. job 
      // 5. sleep 
     } 

    } 
} 

und wir daemonize es mit start-stop-daemon die standardmäßig SIGTERM (TERM) Signal sendet auf --stop

Lassen Sie uns der aktuelle Schritt # ausgeführt vermuten ist 2. Und in diesem Moment senden wir TERM-Signal.

Was passiert ist, dass die Ausführung sofort beendet wird.

Ich habe festgestellt, dass ich das Signalereignis addShutdownHook() mit umgehen kann, aber die Sache ist, dass es nach wie vor die aktuelle Ausführung unterbricht und übergibt die Steuerung an Handler:

public class Hellow { 
    private static boolean shutdownFlag = false; 
    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 
     // TODO code application logic here 
     registerShutdownHook(); 

     try { 
      doProcessing(); 
     } catch (InterruptedException ex) { 
      System.out.println(ex); 
     } 
    } 

    static private void doProcessing() throws InterruptedException { 
     int i = 0; 
     while(shutdownFlag == false) { 
      i++; 
      System.out.println("i:" + i); 
      if(i == 5) { 
       System.out.println("i is 5"); 
       System.exit(1); // for testing 
      } 

      System.out.println("Hello"); // It doesn't print after System.exit(1); 

      Thread.sleep(1000); 
     } 
    } 

    static public void setShutdownProcess() { 
     shutdownFlag = true; 
    } 

    private static void registerShutdownHook() { 
     Runtime.getRuntime().addShutdownHook(new Thread() { 
      public void run() { 
       System.out.println("Tralala"); 
       Hellow.setShutdownProcess(); 
      } 
     }); 
    } 
} 

Also, meine Frage ist - ist es möglich, die laufende Ausführung nicht zu unterbrechen, sondern das Signal in einem getrennten Thread (?) zu behandeln, so dass ich shutdown_flag = True setzen könnte, so dass Schleife in main eine Chance hätte, ordnungsgemäß zu stoppen?

Antwort

1

ich neu geschrieben, die registerShutdownHook() Methode und jetzt funktioniert es, wie ich wollte.

private static void registerShutdownHook() { 
    final Thread mainThread = Thread.currentThread(); 
    Runtime.getRuntime().addShutdownHook(new Thread() { 
     public void run() { 
      try { 
       System.out.println("Tralala"); 
       Hellow.setShutdownProcess(); 
       mainThread.join(); 
      } catch (InterruptedException ex) { 
       System.out.println(ex); 
      } 

     } 
    }); 
} 
0

Sie können SignalHandler verwenden. Bitte überprüfen Sie dieses Beispiel: https://dumpz.org/2707213/

Es wird aufholen INTERRUPTED signal und unset operating flag, die wiederum App ordnungsgemäß herunterfahren erlaubt.

enter image description here

+0

Ja, Ihre Lösung funktioniert, aber zur Kompilierzeit schwört der Compiler, dass 'SignalHandler' in der Zukunft nicht funktioniert. Ich habe eine andere Lösung gefunden, aber danke) –

Verwandte Themen