Process对象.waitFor()的阻塞问题(坑)

有时需要在程序中调用可执行程序或脚本命令:

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();
      }
}

 

 

 

阅读更多
个人分类: java
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭