上篇博文中CallMaxentThreadPoolTask類直接使用Runtime.getRuntime().exec方法調用cmd命令,結果今天在測試時發現當cmd命令執
行出現錯誤或警告時,主控程式的waitfor方法會被阻塞一直等待下去,查了查資料發現是Runtime.getRuntime().exec方法需要自己處理
stderr 及stdout流,而解決方案即是將它們匯出用別的thread處理。
會造成阻塞的代碼:
Process p = Runtime.getRuntime().exec(cmd);</p><p>p.waitFor();
解決方案:
Process p = Runtime.getRuntime().exec(cmd);</p><p>StreamGobbler errorGobbler = new StreamGobbler(p.getErrorStream(), "ERROR"); </p><p> // kick off stderr<br /> errorGobbler.start();</p><p> StreamGobbler outGobbler = new StreamGobbler(p.getInputStream(), "STDOUT");<br /> // kick off stdout<br /> outGobbler.start(); </p><p>p.waitFor();
其中StreamGobbler類的代碼:
package com.sdc.callmaxent.socket;</p><p>import java.io.BufferedReader;<br />import java.io.IOException;<br />import java.io.InputStream;<br />import java.io.InputStreamReader;<br />import java.io.OutputStream;<br />import java.io.PrintWriter;</p><p>import com.sdc.callmaxent.util.FileUtil;</p><p>/**<br /> * 用於處理Runtime.getRuntime().exec產生的錯誤流及輸出資料流<br /> * @author shaojing<br /> *<br /> */<br />public class StreamGobbler extends Thread {<br />InputStream is;<br />String type;<br />OutputStream os;</p><p>StreamGobbler(InputStream is, String type) {<br />this(is, type, null);<br />}</p><p> StreamGobbler(InputStream is, String type, OutputStream redirect) {<br /> this.is = is;<br /> this.type = type;<br /> this.os = redirect;<br /> }</p><p> public void run() {<br /> InputStreamReader isr = null;<br /> BufferedReader br = null;<br /> PrintWriter pw = null;<br /> try {<br /> if (os != null)<br /> pw = new PrintWriter(os);</p><p> isr = new InputStreamReader(is);<br /> br = new BufferedReader(isr);<br /> String line=null;<br /> while ( (line = br.readLine()) != null) {<br /> if (pw != null)<br /> pw.println(line);<br /> System.out.println(type + ">" + line);<br /> }</p><p> if (pw != null)<br /> pw.flush();<br /> } catch (IOException ioe) {<br /> ioe.printStackTrace();<br /> } finally{<br /> FileUtil.close(pw);<br /> FileUtil.close(br);<br /> FileUtil.close(isr);<br /> }<br /> }<br />}<br />
感謝http://faq.csdn.net/read/200584.html中提到的各位。