【问题标题】:Is there a way to dynamically restart a HelloWorld Java program which loops print outputs?有没有办法动态重启循环打印输出的 HelloWorld Java 程序?
【发布时间】:2015-05-04 08:04:39
【问题描述】:

考虑以下永远打印“Hi world”的简单代码:

public class WakeMeUpSomehow {

 public static void main(String[] args) {

    while (true) {
    try {
         System.out.println( " Hi world ");
         Thread.sleep(1000);                 //1000 milliseconds is one second.
    } catch(InterruptedException ex) {
         Thread.currentThread().interrupt();
    }
    }
 }
}

这是输出:

有没有办法设计一个外部的第三个程序,当我们杀死它时它会观察这个程序(比如在命令行中使用 CTRL+C);然后这个“父”程序继续运行“Hello World”?

我认为它可能看起来像这样:

所以我的问题是 - 我怎样才能模拟这样的代码,它具有这种故障安全能力?有没有办法做到这一点?

谢谢!

编辑:我在这里找到了一个相关的简洁链接,但解决了一些不同的问题-How can I restart a Java application?

【问题讨论】:

  • @AbdulAhmad - 我想是的,怎么样
  • 在 Linux 中,您通常会使用 init 进程(例如 upstart 或 systemd)来监督长时间运行的服务。也许 Windows 也有类似的东西?
  • @ChrisMartin - 所以对于 Linux,这项任务很容易吗?我可以尝试在虚拟机上使用 Linux
  • “Easy”是一个延伸,仅仅为了这个就有点过头了,但也许是一个很好的学习练习? :)

标签: java restart


【解决方案1】:

关闭钩子保证在程序的正常关闭事件上运行,但不能在各种异常终止时运行,例如当 JVM 被强制终止时。

一种解决方案可能是使用批处理脚本:

@echo off
setlocal

start /wait java WakeMeUpSomehow

if errorlevel 1 goto retry
echo Finished successfully
exit

:retry
echo retrying...
start /wait java WakeMeUpSomehow

【讨论】:

  • 这可以称为“看门狗脚本”。
【解决方案2】:

如果就这么简单,你可以简单地使用一个shutdownhook。

Runtime.getRuntime().addShutdownHook(() -> {
    //do whatever you want to be done when closing the program here
});

虽然你可能会遇到一些问题,但如果你想重新启动程序并使用相同的命令行。

【讨论】:

  • 所以我猜addShutdownHook() 代码可以放在原始类中,然后我们可以做任何我们喜欢的事情
  • 没错。只需在进入 while 循环之前添加它,它就会完成它的工作
  • 一条评论 - 我确实让它工作了,但是.... 大括号里面有一个线程对吗?
  • 参数是Runnable。 addShutDownHook 创建一个处于初始化状态的Thread,它将在应用程序退出时启动。大括号内是 ShutDownHook 启动时将运行的代码。
  • 你们中的任何人都可以在这里发布完整的代码吗?我试过了,但工作没有奏效:(
【解决方案3】:

首先,这是一项具有挑战性的任务。试试看,让我知道它是否有效!!!!

public class WakeMeUpSomehow {
    static class Message extends Thread {

        public void run() {
            try {

                while(true)
                {
                System.out.println("Hello World from run");

                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        try {
            Runtime.getRuntime().addShutdownHook(new Message());
            while(true)
            {
            System.out.println("Hello World");
            Thread.sleep(100);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

【讨论】:

  • 当我尝试用 CTRL + C 杀死程序时,它实际上进入了一个无限循环(打印 "hello world from run" ),我不能 CTRL + C 它
  • 这就是你想要的
【解决方案4】:

您可以使用关闭挂钩再次启动您的应用程序。请注意这样做的缺点 - 你的 JVM 永远不会停止运行,直到你强制杀死它。

http://wrapper.tanukisoftware.com/doc/english/qna-shutdown.html

【讨论】:

  • 您介意分享该链接上的内容吗?我犹豫是否打开外部链接
【解决方案5】:

如果不详细说明您想要这样做的原因:-),执行此操作的“稳健”方法是在以下位置执行您的“父”程序或批处理脚本:

  1. Windows 服务执行 java 程序,详见Install java program as a windows service: Alternative to JavaService?
  2. 3PP 调度程序
  3. 如果您使用的是 Linux,则可以使用 init 守护程序或 Cron 调度程序。

上述方法甚至可以承受计算机重启!

【讨论】:

  • 好奇,3PP schedulers 是什么?
  • 3PP 代表 3rd Party Publishers :-) 即他人开发的软件。例如,查看quartz-scheduler.org,这是最著名的 Java 应用程序调度程序之一
【解决方案6】:

您应该结帐monit。它提供了许多实用程序,而不仅仅是重新启动程序。

例如

  1. 它会检查您的程序是否正在消耗更多内存(可能是由于内存泄漏)。
  2. 监控文件更改。
  3. 如果程序崩溃,请重新启动程序。
  4. 基于脚本的自定义启动选项支持。

【讨论】:

    【解决方案7】:

    听起来您希望将应用程序作为 Service ( windows ) 或 Daemon ( Unix ) 运行。

    在 Java 中,您通常为此使用服务包装器。我为此使用Apache Commons Daemon。

    Commons Daemon 在 Windows 上提供 ProcRun.exe 用于将 Java 应用程序作为服务运行。您甚至可以将可执行文件重命名为您的程序的可执行文件。在 Unix 上,您有 JSvc 用于重新启动您的 Java 应用程序。我在我的主类中编写了一个精简的通用启动 API,它被两个可执行文件调用。

    如果您需要在生产中执行此操作(而不是作为某种练习),我相信这是唯一可以可靠地执行此操作的方法。

    【讨论】:

    • 我觉得这很有趣。它说but in those cases where the application is not interactive (server applications) there is currently no portable way to notify the Virtual Machine of its imminent shutdown. - 尽管我如何使用它仍然有点模糊。所以你创建了一些代码来重启你自己的程序?
    • @Coffee Commons Daemon 通过提供一个小的本机可执行文件来工作,该可执行文件可以在自己的进程空间中运行 JVM 或托管 jvm.dll。然后它以各种 API 方法调用您的应用程序,包括当它捕获系统信号时(例如 CTRL+C )。结果是应用程序可以作为服务运行(甚至以交互方式)。许多生产 Java 服务器应用程序都使用这种方法。
    • JSvc 与supervise 工具相比如何?我查找了一个叫做 daemontools 的东西,发现这个东西叫做 `supervise' ?好奇我们是否知道这一点
    【解决方案8】:

    在 Windows 中,执行此操作的方法是将程序作为服务运行。它允许在系统启动时启动程序(没有用户登录)并在程序关闭时重新启动程序。 Windows 资源工具包提供了一个名为 SrvAny.exe 的程序,允许您将任何程序作为服务运行。

    https://support.microsoft.com/en-us/kb/137890

    【讨论】:

    • 嗯?不知道我明白你的意思
    猜你喜欢
    • 1970-01-01
    • 2016-05-31
    • 1970-01-01
    • 1970-01-01
    • 2021-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多