2016-06-28 136 views
0

我有一个在外部进程中运行shell脚本中的线程和我使用的Apache的IOUtils从这个外部进程的标准错误和标准输出流如下:线程停止执行

Thread t = new Thread(()-> { 
     ProcessBuilder pb = new ProcessBuilder("sh"); 
     Process p = null; 
     try { 
      p = pb.start(); 
      OutputStream os = p.getOutputStream(); 
      os.write("sleep 30 ; echo test".getBytes()); 
      os.flush(); 
      os.close(); 
      InputStream is = p.getInputStream(); 
      InputStream es = p.getErrorStream(); 
      String stdout = IOUtils.toString(is,"UTF-8"); 
      String stderr = IOUtils.toString(es,"UTF-8"); 
      int retval = p.waitFor(); 
     } catch (Exception e) { 
      System.out.println("Got exception: "+e.toString()); 
     } finally { 
      System.out.println("Done now!"); 
     } 
    }); 
t.start(); 
Thread.sleep(7000); 
t.interrupt(); 

出于某种原因,运行此测试用例时,从不抛出异常(catch块永不运行),并且finally块永不运行。有没有一些问题我不抓住? stdout和stderr应该由另一个线程收集吗?

回答

3

如果stderr的缓冲区填满,程序将停止。除非你需要它们在不同的字符串中,否则我会将其重定向到另一个字符串。

我会用ProcessBuidler.redirectErrorStream的输出组合,所以你不需要额外的线程来读取标准错误

waitFor(long, TimeUnit)有超时,所以你不需要启动一个后台线程。

我建议你打印出你的stderr和stdout,这样你就可以看到他们,因为他们可能会指出什么是错的。

1

看起来是正确的,除了线程在可以处理shell的任何输出之前被终止(中断)。问题是外壳睡了30秒,线程在7秒内中断。

实际上,在“shell”线程实际激活之前,您看不到任何来自catch或finally块的消息可能是由于从main()方法中退出程序所致。