Java线程问题-侦听n个错误流
首先让我说,我对线程的经验非常低 我有一个应用程序可以通过Java线程问题-侦听n个错误流,java,multithreading,Java,Multithreading,首先让我说,我对线程的经验非常低 我有一个应用程序可以通过Runtime.exec方法启动其他几个Java JAR。问题是启动的jar需要同时运行,但是为了获得启动的jar的错误流,基本上必须有一个循环“静坐并侦听”,直到流程完成 这就是我现在拥有的: _processes.add( Runtime.getRuntime().exec( commandList.toArray( new String[ commandList.size() ] ) ) ); Thread thread = new
Runtime.exec
方法启动其他几个Java JAR。问题是启动的jar需要同时运行,但是为了获得启动的jar的错误流,基本上必须有一个循环“静坐并侦听”,直到流程完成
这就是我现在拥有的:
_processes.add( Runtime.getRuntime().exec( commandList.toArray( new String[ commandList.size() ] ) ) );
Thread thread = new Thread( new Runnable() {
private final int _processNumber = _processes.size() - 1;
public void run() {
String streamData = _processNumber + " : ";
streamData += "StdError [\r";
BufferedReader bufferedReader =
new BufferedReader( new InputStreamReader( _processes.get( _processNumber ).getErrorStream() ) );
String line = null;
try {
while ( ( line = bufferedReader.readLine() ) != null ) {
streamData += line + "\r";
}
bufferedReader.close();
streamData += "]\r";
LOG.error( streamData );
}
catch ( Exception exception ) {
LOG.fatal( exception.getMessage() );
exception.printStackTrace();
}
}
} );
thread.start();
有人能解释一下如何让“错误流侦听器线程”正常工作吗
TIA关于如何使用Runtime.exec()有一个非常好的教程。通读所有内容,尤其是第4页,其中解释了如何使用在单独线程中运行的“StreamGobbler”来使用正在执行的进程中的std out和std err流 基本上,您应该在psedoo代码中实现的是:
Runtime rt1 = Runtime.getRuntime().exec("my command")
new StreamGobbler(rt1.getOutputStream()).start()
new StreamGobbler(rt1.getErrorStream()).start()
//repeat for each external process (rt2, rt3 etc)
...
rt1.waitFor()
rt2.waitFor()
rt3.waitFor()
即,启动每个进程,并立即开始在单独的线程中使用每个进程的输出。消费线程启动后,只需等待每个进程完成并返回。使用Runtime.getRuntime().exec()来启动外部进程,而不是使用Runtime.getRuntime().exec()。。这会让你的生活更轻松 矿山项目的示例代码:
//Build command
List<String> commands = new ArrayList<String>();
commands.add("my_application");
commands.add("arg1");
commands.add("arg2");
log.debug("{}", commands);
//Run command with arguments
ProcessBuilder pb = new ProcessBuilder(commands);
pb.directory(directory);
pb.redirectErrorStream(true);
Process process = pb.start();
//Read output
StringBuilder out = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader
(process.getInputStream()));
//Only log unique lines (you might not need this)
String line = null, previous = null;
while ((line = br.readLine()) != null)
if (!line.equals(previous)) {
previous = line;
out.append(line).append('\n');
log.debug(line);
}
//Check result
if (process.waitFor() == 0)
return 0;
//Abnormal termination: Log command parameters and output and throw ExecutionException
log.error("{}", commands);
log.error("\n{}", out.toString());
throw new ExecutionException(new IllegalStateException("MyApplication exit code 1"));
//Build命令
List命令=new ArrayList();
commands.add(“我的应用程序”);
命令。添加(“arg1”);
命令。添加(“arg2”);
调试(“{}”,命令);
//使用参数运行命令
ProcessBuilder pb=新的ProcessBuilder(命令);
pb.目录(directory);
pb.重定向错误流(真);
Process进程=pb.start();
//读取输出
StringBuilder out=新的StringBuilder();
BufferedReader br=新的BufferedReader(新的InputStreamReader
(process.getInputStream());
//仅记录唯一行(您可能不需要)
String line=null,previous=null;
而((line=br.readLine())!=null)
如果(!line.equals(上一个)){
上一个=行;
out.append(line.append('\n');
log.debug(行);
}
//检查结果
if(process.waitFor()==0)
返回0;
//异常终止:记录命令参数、输出和抛出ExecutionException
错误(“{}”,命令);
log.error(“\n{}”,out.toString());
抛出新的ExecutionException(新的IllegalStateException(“MyApplication退出代码1”);
是的,我以前读过。问题是rt1正在打开侦听套接字,而rt2正在打开套接字的写端。如果我启动2个线程以从rt1的流中获取数据,那么父线程似乎会阻塞,rt2永远不会启动。我试过运行所有exec命令,然后启动所有侦听器,当我这样做时,它会强制执行命令阻塞。我认为产生的线程及其相应流的并发性是这里的问题。我在ProcessBuilder(或者在所有Java中)中看不到处理过程更好的地方。上面列出的文章中提到了jconfig,但显然这个项目已经死了(至少现在是这样)?