上篇博文中CallMaxentThreadPoolTask类直接使用Runtime.getRuntime().exec方法调用cmd命令,结果今天在测试时发现当cmd命令执
行出现错误或警告时,主控程序的waitfor方法会被阻塞一直等待下去,查了查资料发现是Runtime.getRuntime().exec方法需要自己处理
stderr 及stdout流,而解决方法即是将它们导出用别的thread处理。
会造成阻塞的代码:
- Process p = Runtime.getRuntime().exec(cmd);
- p.waitFor();
解决方法:
- Process p = Runtime.getRuntime().exec(cmd);
- 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类的代码:
- package com.sdc.callmaxent.socket;
- 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中提到的各位。