Process对象.waitFor()的阻塞问题(坑)
有时需要在程序中调用可执行程序或脚本命令:Process process = Runtime.getRuntime().exec(shPath);int exitCode = process .waitFor();Runtime.getRuntime()返回当前应用程序的Runtime对象,该对象的exec()方法指示Java虚拟机创建一个子进程执行指定的可执行程序,并返回与该子进程对...
有时需要在程序中调用可执行程序或脚本命令:
Process process = Runtime.getRuntime().exec(shPath);
int exitCode = process .waitFor();
Runtime.getRuntime()返回当前应用程序的Runtime对象,该对象的exec()方法指示Java虚拟机创建一个子进程执行指定的可执行程序,
并返回与该子进程对应的Process对象实例。通过Process可以控制该子进程的执行或获取该子进程的信息。
它的所有标准io(即stdin,stdout,stderr)操作都将通过三个流(getOutputStream(),getInputStream(),getErrorStream())重定向到父进程。
父进程使用这些流来提供到子进程的输入和获得从子进程的输出。因为有些本机平台仅针对标准输入和输出流提供有限的缓冲区大小,如果读
写子进程的输出流或输入流出现失败,则可能导致子进程阻塞,甚至产生死锁。(如果程序不断在向标准输出流和标准错误流写数据,而JVM不读取的话,当缓冲区满之后将无法继续写入数据,最终造成阻塞在waifor()这里。)
process .getErrorStream():获得子进程的错误输出流
process .getInputStream():获得子进程的普通输出流
简单示例:
Process shellProcess = null;
try {
shellProcess = Runtime.getRuntime().exec(shPath);
shellErrorResultReader = new BufferedReader(new InputStreamReader(shellProcess.getErrorStream()));
shellInfoResultReader = new BufferedReader(new InputStreamReader(shellProcess.getInputStream()));
String infoLine;
while ((infoLine = shellInfoResultReader.readLine()) != null) {
logger.info("脚本文件执行信息:{}", infoLine);
}
String errorLine;
while ((errorLine = shellErrorResultReader.readLine()) != null) {
logger.warn("脚本文件执行信息:{}", errorLine);
}
// 等待程序执行结束并输出状态
exitCode = shellProcess.waitFor();
if (0 == exitCode) {
logger.info("脚本文件执行成功:" + exitCode);
} else {
logger.error("脚本文件执行失败:" + exitCode);
}
} catch (Exception e) {
logger.error("shell脚本执行错误", e);
} finally {
if (null != shellInfoResultReader) {
try {
shellInfoResultReader.close();
} catch (IOException e) {
logger.error("流文件关闭异常:", e);
}
}
if (null != shellErrorResultReader) {
try {
shellErrorResultReader.close();
} catch (IOException e) {
logger.error("流文件关闭异常:", e);
}
}
if (null != shellProcess) {
shellProcess.destroy();
}
}
更多推荐
所有评论(0)