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,但显然这个项目已经死了(至少现在是这样)?