2016-06-28 215 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()方法中退出程序所致。