项目中遇到的 Java啤酒爆炸

    最近在做一项目,其中有一模块需要在页面上配置第三方提供的程序路径,配置完成后系统定时执行(quartz),也可以在页面上手动执行,ajax调用后台方法,执行第三方提供的程序,只要是读取固定格式的文件解析成图片,存到本地目录和数据库中。当要解析的文件很大的时候,就会遇到啤酒爆炸的问题。。。

    File file = new File(pro);
        if (file.exists()) {
          logger.info("seed程序开始执行....");
          ProcessBuilder procBuilder = new ProcessBuilder(file.getAbsolutePath());
          procBuilder.redirectErrorStream(true); //合并输出子进程的standard和error inputstream
          logger.info("合并子进程InputStream{}",procBuilder.redirectErrorStream());
          Process process = procBuilder.start();
         
          drainInBackground(process.getInputStream());
          int exit = process.waitFor();
          logger.info("seed程序退出{}", exit);
          josnResult = "exeok";
        } else {
          logger.info("seed程序未找到....");
          josnResult = "notfound";
        }

 

    /**
   * 启动一个线程,用于排空子进程的输出流,否则子进程会挂起
   */
  static void drainInBackground(final InputStream is) {
    new Thread(new Runnable() {
      public void run() {
        try {
          while (is.read() >= 0)
            ;
        } catch (IOException e) {
          // return on IOException
        }
      }
    }).start();
  }

 

    这里的教训是: 为了确保子进程能够结束,你必须排空它的输出流;对于错误流(error stream)也是一样,而且它可能会更麻烦,因为你无法预测进程什么时候会倾 倒(dump)一些输出到这个流中。在 5.0 版本中,加入了一个名为ProcessBuilder 的类用于排空这些流。它的 redirectErrorStream 方法将各个流合并起来,所以你只需要排空这一个流。如果你决定不合并输出流和错误流,你必须并行地 (concurrently)排空它们。试图顺序化地(sequentially)排空它们会导致子进程被挂起。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值