Java中提供了两种方法来启动其它进程:
方法一:
Process process = new ProcessBuilder(cmd).start();
方法二:
Process process = Runtime.getRuntime().exec(cmd);
注意:底层也是调用方法一。缓存
Process的waitFor()方法:
说明:等待Process结束后返回Process的返回值,若Process一直未结束,则程序一直等待下去。
分析:
建立的新进程与jvm创建三个管道链接:标准输入流、标准输出流、标准错误输出流。
若新进程不断向标准输入流、标准错误输出流写数据,而jvm不读取的话,则会致使缓冲区塞满而没法继续写数据,从而形成新进程一直不结束,最终致使调用waitFor()方法的线程阻塞。
解决:
jvm读取新进程写入缓存区的数据(即:标准输入流Process.getInputStream()、标准错误输出流Process.getErrorStream()中的数据)便可。
eg:
// 打印进程的输出信息
List<String> outputStr = IOUtils.readLines(process.getInputStream(), "UTF-8");
List<String> errorOutputStr = IOUtils.readLines(process.getErrorStream(), "UTF-8");
LOGGER.info("=============new process output start =======");
LOGGER.info(outputStr.toString());
LOGGER.info("=============new process output end =======");
LOGGER.info("=============new process error output start =======");
LOGGER.info(errorOutputStr.toString());
LOGGER.info("=============new process error output end =======");jvm
相关源码:
/**
* Causes the current thread to wait, if necessary, until the process represented by this {@code Process} object has terminated.
* This method returns immediately if the subprocess has already terminated.
* If the subprocess has not yet terminated, the calling thread will be blocked until the subprocess exits.
*/
public synchronized int waitFor() throws InterruptedException {
while (!hasExited) {
wait();
}
return exitcode;
}ui
/**
* Returns the input stream connected to the normal output of the subprocess.
* The stream obtains data piped from the standard output of the process represented by this {@code Process} object.
*/
public abstract InputStream getInputStream();this
/**
* Returns the input stream connected to the error output of the subprocess.
* The stream obtains data piped from the error output of the process represented by this {@code Process} object.
*/
public abstract InputStream getErrorStream();.net
/**
* Returns the output stream connected to the normal input of the subprocess.
* Output to the stream is piped into the standard input of the process represented by this {@code Process} object.
*/
public abstract OutputStream getOutputStream();线程