在我的Java 11(Debian下为openjdk 11.0.3 2019-04-16)程序中,我使用ProcessBuilder启动外部命令。外部命令可能会挂起,因此我需要它在给定的时间后超时。
所以我用p.waitFor(time, unit)
应该返回
如果进程已退出,则为true;如果进程已退出,则等待时间为false。
ProcessBuilder pb = new ProcessBuilder(externalCommand);
// Merges the error stream with the standard output stream
pb.redirectErrorStream(true);
Process p = pb.start();
Date start = new Date();
BufferedReader br = new BufferedReader(new InputStreamReader(
p.getInputStream()));
String tempLine;
/**
* We only want the first 10 lines otherwise it will print thousands of
* useless lines (always the same)
*/
int nbOfLinesInlogs = 10;
while ((tempLine = br.readLine()) != null) {
// We only report errors to the user
if (tempLine.toLowerCase().startsWith("error") && nbOfLinesInlogs > 0) {
Level level = Level.WARNING;
System.err.println("External command output : " + tempLine);
// There was an error
errorDetected = true;
nbOfLinesInlogs--;
}
}
if (p.waitFor(10l,
TimeUnit.NANOSECONDS)) {
long elapsedInMillis = new Date().getTime() - start.getTime();
System.err.println("External process succeeded and took " + elapsedInMillis + " ms");
// prints Externalprocess succeeded and took 15327 ms
...
}
else {
System.err.println("External process timed out");
// This is never printed!
throw new InterruptedException(
"External process timed out!");
}
但是该过程永远不会超时并打印花费了15 s,尽管它应该在10 ns后超时(这只是一项检查超时是否按预期工作的测试)。我还尝试了µs,ms和s,结果相同。
如何使进程超时时返回假?
任何帮助表示赞赏,
答案 0 :(得分:0)
感谢您的评论。根据上面的评论,一种解决方案是删除流程启动和流程等待流程(1.0.0
)之间的代码段
waitFor(...)
原因是(请参阅@TreffnonX评论)
因为我使用了while循环,一旦输入关闭,它只会返回false。由于我的输入仅在流程终止时关闭,因此我的检查(waitFor)在流程结束后进行。
另一个解决方案可能是启动一个单独的线程,该线程将在while循环中运行。