我想通过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()unblocks),但主线程阻塞直到batch2.bat并且javaw.exe已终止,因为“errorLogger.join()”和“outputLogger.join()”。我对阅读batch2.bat的输出不感兴趣;如何在batch1.bat完成后让我的主线程返回?
答案 0 :(得分:0)
当您使用waitFor
方法时,如果batch2.bat
在与batch1.bat
相同的流程上运行,则必然会发生这种情况。
在我的头脑中,我会说你有几个选择(如果你真的想等待第一批文件完成执行):
outputlogger
发送标记,告知您的父进程batch1.bat
已完成执行且不使用waitFor
。这将有助于您继续使用代码逻辑。答案 1 :(得分:0)
您是否尝试通过start / b batch2.bat调用第二批?