Java应用程序在关闭时如何重启?

时间:2015-05-28 12:03:40

标签: java

我想在停止时重启一个java应用程序。 此stackoverflow question解决了如何启动Java应用程序的问题。

是否有可能在程序关闭时重启程序?或者在退出前保存其状态?

我的第一种方法是尝试运行一个传递以下Runnable实现的线程:

public void run() {
    try {
        while(true) {
            // perform important computations
        }
    }
    catch(Throwable t) {
        // save state before exiting and start again
        System.out.println("saving...");
    }       
}

这不起作用,因为当我按 Ctrl + C 时,程序不会产生任何输出,这意味着任何带有ProcessBuilder的代码都不会运行太。

如果不可能,我如何使用其他编程语言或使用操作系统设置(例如UNIX)使应用程序保持运行(停止关闭和/或在关闭后再次启动它)?

更新:我使用pens-fan-69的代码和ProcessBuilder实例。作为参考,以下是代码的外观:

public class Unkillable {

  public static void main(String[] args) {
      System.out.println("I'm running!");
      Runtime runtime = Runtime.getRuntime();
      runtime.addShutdownHook(new Thread() {
          @Override
          public void run() {
              // save state before exiting and start again
              System.out.println("Shuting down...");
              ProcessBuilder pb = new ProcessBuilder("java", "Unkillable");
              try {
                  pb.start();
              } catch (IOException e) {
                  System.out.println("Error executing callback function.");
              }
          }
      });

      while(true) {
          // fancy code goes here
      }
  }
}

这带来了副作用:当你在控制台上运行它时,点击 Ctrl + C 将使程序不可见,在后台运行。然后我可以通过活动监视器杀死剩余的进程。如果该类接收到来自用户的输入,则这将没什么用处。我想知道是否有新的流程与控制台或类似的东西相关联。

3 个答案:

答案 0 :(得分:1)

你可以在linux上为它做一个cron工作。

e.g。 http://java.dzone.com/articles/how-automatically-recover

此示例将向您展示如何在崩溃时启动tomcat。

答案 1 :(得分:1)

您可以添加将在有序应用程序关闭期间运行的关闭挂钩。你会这样做:

Runtime runtime = Runtime.getRuntime();
runtime.addShutdownHook(new Thread() {
    @Override
    public void run() {
        // save state before exiting and start again
        System.out.println("saving...");
    }
});

但是,您应该注意,这不会涵盖外部信号杀死进程或JVM无法有序关闭的情况。

http://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/signals.html讨论了JVM上下文中的信号主题,您可以查看http://en.wikipedia.org/wiki/Unix_signal来详细讨论POSIX信号。请注意,即使您实现本机或java信号处理程序,也有一些无法处理的信号(例如Linux / Unix上的SIGKILL)

答案 2 :(得分:0)

请注意,服务中可能会运行一些线程,这些线程会重新打开通知