我是线程世界的新手,一直试图解决这个问题一周。
由于某种原因没有调用Thread类中的run方法,我不知道为什么(但很想知道)
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("/bin/sh", "-c", "echo \"w30000001z,none,16488,,181075\nw30000001z,none,16488,,181082\n\" | /home/beehive/bin/exec/tableSize");
Process process = processBuilder.start();
process.waitFor();
InputStream stdin = process.getInputStream();
OutputStream stdout = process.getOutputStream();
InputStream stderr = process.getErrorStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(stdin));
BufferedReader error = new BufferedReader(new InputStreamReader(stderr));
StreamGobbler errorStream = new StreamGobbler(process.getErrorStream(), "ERROR");
StreamGobbler outputStream = new StreamGobbler(process.getInputStream(), "OUTPUT");
errorStream.start();
outputStream.start();
errorStream.join();
outputStream.join();
tableSize是一个python可执行文件,它通过stdin获取输入,处理它并输出几行文本。我需要收集此输出并对其进行进一步处理。
有一个单独的线程来处理inputStream和errorStream上的输出。该线程类如下所示。
/* StreamGobbler.java */
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
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()
{
try
{
PrintWriter pw = null;
if (os != null)
pw = new PrintWriter(os);
System.out.println("Ajay" + type);
InputStreamReader isr = new InputStreamReader(is);
BufferedReader 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();
}
}
}
由于某种原因,未调用StreamGobbler类中的run方法。但是这个类的构造函数正在执行。
非常感谢任何帮助。
答案 0 :(得分:9)
您需要在致电process.waitFor()
之前启动流gobblers 。
流gobblers读取并丢弃外部进程输出/错误流,以便外部进程在尝试写入时不会阻塞。但是你拥有它的方式,在你尝试吞噬输出之前,这个过程必须完成写入(和退出)。
结果 - 死锁...如果外部进程对其输出流写入太多。
实际上,我认为主问题是你的Java代码没有向inputStream
写任何东西。因此,外部进程只是坐在那里等待从未到达的输入......并且process.waitFor()
等待外部进程。死锁。
事情的正确顺序应该是:
process.waitFor()
并检查进程返回代码。答案 1 :(得分:1)
您需要在Process.waitFor()
之前使用 STDOUT 和/或 STDERR ,这是一篇很好的文章:
http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=2
答案 2 :(得分:1)
1)如果不需要,请尝试删除waitFor()。它只会使执行线程等到流程执行完成。