如果任何线程崩溃,如何让 shell 脚本重新启动 Java?

如果任何线程崩溃,如何让 shell 脚本重新启动 Java?

我有一个多线程 Java 程序。

理想情况下,它应该运行一次并成功终止。

不幸的是,有时其中一个线程会崩溃,比如抛出 DivisionByZeroException

由于除非所有线程都在运行,否则程序是无用的,因此我想在其中一个线程关闭时完全重新启动 JVM(和程序)。

问题: 我该如何编写一个可以实现该功能的 shell 脚本?

我正在寻找的 shell 脚本的伪代码是:

#bin/bash
while (true) {
   sudo java -jar MyProgram.jar
   if (MyProgram.terminatedWithoutExceptions) { // How to write this part?
       finish;
   } else {
       shutdown JVM;
   }
}

答案1

程序与父 shell 之间的一个最基本的关系是“退出代码”的概念。这是一个简单的整数,按照惯例,它让 shell 知道出现了问题。

零表示“一切顺利”,其他任何内容都表示“omghoustonproblems”。同样,这只是惯例。有些东西(例如grep -q ...)使用退出代码来指示是否匹配。Grep跑了没有错误,但它使用退出代码来发出其他信号。

无论如何,我假设如果您的 Java 应用程序崩溃到出现分段错误或其他问题的地步,它就不会干净地退出。因此,它发送回父 shell 的退出代码不是零。这使得测试变得非常容易:

while true; do
    sudo java -jar MyProgram.jar
    if [ $? -eq 0 ]; then
        // it exited cleanly, do something good
    else
        // it crashed out, do something else
    fi
done

如果您想要退出其中一个 if 子句中的 while 循环,请插入break

以 root 身份运行 Java 程序真的是个好主意吗?谁知道呢。我不知道这个外部脚本是以谁的身份运行的,所以目前无法判断,但如果可以的话,请考虑重构它。


以上内容是准确的,但重新阅读您的问题后,您可能想要更改线程池的方式。自从我使用 Java 进行任何线程工作以来,已经过去了大约 13 年,那只是学术上的,但我想到了一些事情:

  • 通过验证输入可以避免除以零的问题。
  • 它们也是可以捕获的。不要让它们破坏线程。捕获、记录并继续。
  • 让线程崩溃而不启动新线程的线程运行器是垃圾。请寻找更强大的东西。

最好的解决方案不是在事情出错时进行清理,而是从一开始就阻止事情发展到那个地步。这是可以做到的。

相关内容