今日開發的時候使用jdk自帶的運行時變量 RunTime.getRunTime() 去執行bash命令。
由於該bash操做耗時比較長,因此使用了Process.waitFor()去等待子線程運行結束。java
這個時候發現程序卡在waitFor()沒有繼續往下執行。
看了官方解釋:bash
waitFor:等待子進程執行結束,或者已終止子進程,此方法當即返回。
當RunTime對象調用exec方法後,jvm會建立一個子進程,該子進程與jvm創建三個管道鏈接:標準輸入流、標準輸出流、標準錯誤流。假設該子進程不斷向標準輸入流、標準輸出流寫數據,而jvm不讀取的話,會致使緩衝區塞滿而沒法繼續寫數據,最終堵塞在waitFor這裏。app
知道了問題所在就好處理了, 咱們只須要將子進程返回的信息從緩衝區讀取出來,即可以免主線程堵塞問題。jvm
public static void main(String[] args){ Process proc = RunTime.getRunTime().exec("sh /home/winnie/dataExtract.sh") // 標準輸入流(必須寫在 waitFor 以前) String inStr = consumeInputStream(proc.getInputStream()); // 標準錯誤流(必須寫在 waitFor 以前) String errStr = consumeInputStream(proc.getErrorStream()); int retCode = proc.waitFor(); if(retCode == 0){ System.out.println("程序正常執行結束"); } } /** * 消費inputstream,並返回 */ public static String consumeInputStream(InputStream is){ BufferedReader br = new BufferedReader(new InputStreamReader(is)); String s ; StringBuilder sb = new StringBuilder(); while((s=br.readLine())!=null){ System.out.println(s); sb.append(s); } return sb.toString(); }