【注意】:
Runtime.exec方法将产生一个本地的进程,并返回一个Process子类的实例,该实例可用于控制进程或取得进程的相关信息。由于调用Runtime.exec方法所创建的子进程没有自己的终端或控制台,因此该子进程的标准IO(如stdin,stdou,stderr)都通过 p.getOutputStream(), p.getInputStream(), p.getErrorStream() 方法重定向给它的父进程了。用户需要用这些stream来向子进程输入数据或获取子进程的输出。
但是向标准输出流和标准错误流写数据,而JVM却不读取,数据会暂存在linux缓存区,当缓存区存满之后导致该进程无法继续写数据,会僵死,导致java进程会卡死在waitFor()处。我这里采取的办法是:java进程在waitFor()前不断读取标准输出流和标准错误流。
public class Cmd {
public static void main(String[] args) throws IOException, InterruptedException {
try {
// using the Runtime exec method:
String[] arguments = new String[] { "python", "./pythonSrc/environment.py" };
Process p = Runtime.getRuntime().exec(arguments);
BufferedReader stdInput = new BufferedReader(
new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(p.getErrorStream()));
// read the output from the command
System.out.println("Here is the standard output of the command:\n");
String line = null;
while ((line = stdInput.readLine()) != null) {
System.out.println(line);
}
// read any errors from the attempted command
System.out.println("\nHere is the standard error of the command (if any):\n");
String errline = null;
while ((errline = stdError.readLine()) != null) {
System.out.println(errline);
}
stdInput.close();
stdError.close();
int ret = p.waitFor();
System.out.println("Process exit code: " + ret);
if (ret != 0) {
System.out.println("do something");
}
// System.exit(0);
} catch (Exception e) {
System.out.println("exception happened - here's what I know: ");
e.printStackTrace();
System.exit(-1);
}
System.out.println("=============");
}
}