2017-11-18 378 views
2

假设我们有这样一个平凡的守护java写的:如何在Java中优雅地处理SIGTERM信号?

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 
     } 

    } 
} 

,我们守护进程。它使用start-stop-daemon它默认的--stop

发送SIGTERM(TERM)信号让我们假设执行当前步骤是# 2。在这一刻,我们发送TERM信号。

会发生什么情况是执行立即终止。

我发现我可以用addShutdownHook()处理信号的事件,但事情是,它仍然中断当前执行并传递控制处理程序:

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

所以,我的问题是 - 它可能不会中断当前的执行,但在单独的线程(?)中处理TERM信号,以便我能够设置shutdown_flag = True,以便main中的循环有机会优雅地停止?

回答

1

我重写了registerShutdownHook()方法和现在的作品,因为我想要的。

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

您可以使用SignalHandler。请查看此示例:https://dumpz.org/2707213/

它将赶上INTERRUPTED信号并取消设置operating标志,这反过来将允许应用程序正常关闭。

enter image description here

+0

是的,你的解决方案可以工作,但是在编译时,编译器发誓''SignalHandler'在将来不起作用。我找到了另一个解决方案,但谢谢) –