上篇博文中CallMaxentThreadPoolTask类直接使用Runtime.getRuntime().exec方法调用cmd命令,结果今天在测试时发现当cmd命令执
行出现错误或警告时,主控程序的waitfor方法会被阻塞一直等待下去,查了查资料发现是Runtime.getRuntime().exec方法需要自己处理
stderr 及stdout流,而解决方法即是将它们导出用别的thread处理。
会造成阻塞的代码:
p.waitFor();
解决方法:
StreamGobbler errorGobbler = new StreamGobbler(p.getErrorStream(), "ERROR");
// kick off stderr
errorGobbler.start();
StreamGobbler outGobbler = new StreamGobbler(p.getInputStream(), "STDOUT");
// kick off stdout
outGobbler.start();
p.waitFor();
其中StreamGobbler类的代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import com.sdc.callmaxent.util.FileUtil;
/**
* 用于处理Runtime.getRuntime().exec产生的错误流及输出流
* @author shaojing
*
*/
public class StreamGobbler extends Thread {
InputStream is;
String type;
OutputStream os;
StreamGobbler(InputStream is, String type) {
this(is, type, null);
}
StreamGobbler(InputStream is, String type, OutputStream redirect) {
this.is = is;
this.type = type;
this.os = redirect;
}
public void run() {
InputStreamReader isr = null;
BufferedReader br = null;
PrintWriter pw = null;
try {
if (os != null)
pw = new PrintWriter(os);
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
String line=null;
while ( (line = br.readLine()) != null) {
if (pw != null)
pw.println(line);
System.out.println(type + ">" + line);
}
if (pw != null)
pw.flush();
} catch (IOException ioe) {
ioe.printStackTrace();
} finally{
FileUtil.close(pw);
FileUtil.close(br);
FileUtil.close(isr);
}
}
}
感谢http://faq.csdn.net/read/200584.html中提到的各位。