Process.waitFor()致使主線程堵塞問題

今日開發的時候使用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();
}
相關文章
相關標籤/搜索