【发布时间】:2011-11-03 09:56:34
【问题描述】:
我想通过 Java 的 Runtime::exec 方法运行一个 Windows 批处理文件。在我的批处理文件中,我执行另一个批处理文件来运行 Java 程序。第一个批处理文件使用“start”来执行第二个批处理文件。
我希望我的主线程,即调用 Runtime::exec 的主线程,只等到第一个批处理文件完成,而不关心第二个批处理文件。我在 2 个单独的线程中使用 Process::getInputStream() 和 Process::getErrorStream() 中的所有内容。我的主线程(执行 Runtime::exec 的线程)一直等到 2 个流消费线程完成,然后再继续。
但是,我发现我的主线程总是阻塞,直到第二个批处理文件完成,因为即使在第一个批处理文件完成执行之后,我的流消费线程继续读取。如何让他们忽略第二个批处理文件的输出和错误流?
这是我在主线程中执行第一个批处理文件的方式:
Runtime runtime = Runtime.getRuntime();
String[] cmd = new String[]{"cmd.exe", "/C", "batch1.bat"};
Process proc = runtime.exec(cmd);
StreamLogger errorLogger = new StreamLogger(proc.getErrorStream()); // consume
StreamLogger outputLogger = new StreamLogger(proc.getInputStream()); // consume
errorLogger.start(); // start reading the error stream in another thread
outputLogger.start(); // start reading the output stream in another thread
returnCode = proc.waitFor();
log.debug("Obtained return code");
errorLogger.join();
outputLogger.join();
log.debug("Finished reading from streams");
batch1.bat 看起来像这样:
start "" batch2.bat
exit
在batch2.bat中,我运行了一个java程序(我试过用java.exe或javaw.exe运行它)
javaw.exe -cp . MyProgram 1>outlog 2>errlog
总之,当我运行我的主线程时,我可以在 batch1.bat 完成后获得返回码(即 waitFor() 解除阻塞),但主线程阻塞直到 batch2.bat 和 javaw.exe 终止,因为“errorLogger.join()”和“outputLogger.join()”。我对读取 batch2.bat 的输出不感兴趣; batch1.bat 完成后如何让我的主线程返回?
【问题讨论】:
标签: java process exec runtime.exec