gpt4 book ai didi

java - Apache CommonsExec 异步调用阻止同步调用

转载 作者:行者123 更新时间:2023-12-02 06:55:19 25 4
gpt4 key购买 nike

我使用 CommonsExec 执行了两个调用 - 一个是标准同步调用,其中我调用批处理文件来编译 Maven 项目,下一个也是对运行已编译命令行的批处理文件的异步调用项目。

maven 批处理文件看起来像

call mvn package

此操作完成两次,以编译并启动两个程序。

第一次工作正常,但第二次同步构建调用由于某种原因没有返回,尽管记录的输出显示构建成功完成。该程序显然没有启动。

我还可以通过运行然后编译来重新创建它 - 似乎只要异步调用正在运行,同步调用就不会完成。

有人可以帮忙吗?

上面的代码是

 private static final String LAUNCH_CLIENT_FORMAT = "\"%s\\start.bat\" http://localhost:%d" + ENDPOINT;
private static final String COMPILE_FORMAT = "\"%s\\compile.bat\"";

private static boolean compileAndLaunch(String aiDirectory, int port) {
System.out.println("Compiling " + aiDirectory + " for port " + port);
if (!run(String.format(COMPILE_FORMAT, aiDirectory), aiDirectory))
return false;

System.out.println("Done compiling " + aiDirectory + " for port " + port + ", launching...");
if (!runAsync(String.format(LAUNCH_CLIENT_FORMAT, aiDirectory, port), aiDirectory))
return false;

return true;
}

private static boolean run(String command, String directory) {
DefaultExecutor executor = getExecutor(directory);
System.out.println("Running " + command);
CommandLine commandLine = CommandLine.parse(command);
try {
executor.execute(commandLine);
}
catch (ExecuteException e) {
System.out.println("Failed to execute " + command);
return false;
}
catch (IOException e) {
System.out.println("IO Exception running " + command);
return false;
}
return true;
}

private static DefaultExecutor getExecutor(String directory) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream);
DefaultExecutor executor = new DefaultExecutor();
executor.setWorkingDirectory(new File(directory));
executor.setStreamHandler(streamHandler);
return executor;
}

private static boolean runAsync(String command, String directory) {

CommandLine commandLine = CommandLine.parse(command);
System.out.println("Running async " + command);
DefaultExecutor executor = getExecutor(directory);
DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
try {
executor.execute(commandLine, resultHandler);
}
catch (ExecuteException e) {
System.out.println("Failed to execute " + command);
return false;
}
catch (IOException e) {
System.out.println("IO Exception running " + command);
return false;
}
return true;
}

最佳答案

这是您的回调:

DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();

这是您的异步​​执行器:

executor.execute(commandLine, resultHandler);

但是,在异步模式下,在调用 executor.execute() 之后,该方法将继续,但直到另一个线程中发生某些情况并且 resultHandler.onProcessComplete()resultHandler.onProcessFailed() 被调用,您仍然不知道执行是否结束,并且不应该退出 runAsync() 方法。

我相信将您的方法更改为这样的方法会起作用:

private static boolean runAsync(String command, String directory) {

CommandLine commandLine = CommandLine.parse(command);
System.out.println("Running async " + command);
DefaultExecutor executor = getExecutor(directory);
DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
try {
executor.execute(commandLine, resultHandler);
resultHandler.waitFor();
if(resultHandler.getException() != null){
throw resultHandler.getException();
}
}
catch (ExecuteException e) {
System.out.println("Failed to execute " + command);
return false;
}
catch (IOException e) {
System.out.println("IO Exception running " + command);
return false;
}
return true;
}

因为resultHandler.waitFor()会让线程等待,直到执行结束。

但这和使用同步模式是一样的。只有当两个调用都是异步的时,您才会在性能上获胜,因为它们将并行运行,并且您将等待两个调用都完成。

关于java - Apache CommonsExec 异步调用阻止同步调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17451756/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com