我有一个多线程 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 年,那只是学术上的,但我想到了一些事情:
- 通过验证输入可以避免除以零的问题。
- 它们也是可以捕获的。不要让它们破坏线程。捕获、记录并继续。
- 让线程崩溃而不启动新线程的线程运行器是垃圾。请寻找更强大的东西。
最好的解决方案不是在事情出错时进行清理,而是从一开始就阻止事情发展到那个地步。这是可以做到的。