我尝试使用Process
API从Java运行本机可执行文件。本机代码执行长时间运行的计算,可能必须在超时后中断。
理想情况下,我希望使用getInputStream()
来接收标准输出,避免使用中间文件。
这是一个难题:
waitFor
无限期等待。Thread.interrupt()
。要查看此问题,请参阅以下“最小”示例:模拟长时间运行(5秒)计算的computation.sh
中的Bash代码:
#!/bin/bash
END=$((`date +%s` + 5))
while [ `date +%s` -lt $END ]; do
echo "Heavy computation" > /dev/null
done
echo "Answer is 42"
Test.java
中的Java代码,它在一个单独的线程中运行Bash代码并在1秒后中断它:
import java.io.*;
public class Test {
public static void main(String[] args) throws InterruptedException {
Thread waitForProcess = new Thread() {
@Override
public void run() {
Process unixProcess = null;
try {
unixProcess = new ProcessBuilder("./computation.sh").start();
try (BufferedReader stdout = new BufferedReader(
new InputStreamReader(unixProcess.getInputStream()))) {
String line;
// Exactly here, Java stops
// responding to Thread.interrupt():
while ((line = stdout.readLine()) != null) {
System.out.println(line);
}
}
int retval = unixProcess.waitFor();
System.out.println("Retval: " + retval);
} catch (InterruptedException ex) {
System.out.println("Computation interrupted.");
} catch (IOException ex) {
System.out.println("IOException: " + ex);
} finally {
if (unixProcess != null) {
unixProcess.destroy();
}
}
}
};
waitForProcess.start();
// Timeout of 1000 ms
waitForProcess.join(1000L);
waitForProcess.interrupt();
// Additional grace time
waitForProcess.join(100L);
// Timeout has occured
if (waitForProcess.isAlive()) {
System.out.println("Timeout occurred");
}
}
}
理想情况下,Java代码应打印Timeout occurred
并在1秒后退出。实际上,它等待所有5秒钟并最终打印Answer is 42
。
任何帮助?
答案 0 :(得分:0)
您需要两个线程:一个用于读取输入,另一个用于处理超时。