gpt4 book ai didi

java - ProcessBuilder waitFor() 永远不会返回

转载 作者:行者123 更新时间:2023-11-30 06:30:08 32 4
gpt4 key购买 nike

我正在尝试使用 ProcessBuilder 来执行像“ls”命令这样简单的操作。我已经阅读了有关 waitFor() 调用返回之前需要消耗的进程流的问题,但即使错误重定向到输出并消耗流,进程也永远不会返回。

public class ProcessTest {

public static void main(String[] args) throws Exception {

ProcessBuilder builder = new ProcessBuilder();
builder.command("ls");

builder.redirectErrorStream(true);

Process process = builder.start();

StreamGobbler streamGobbler = new StreamGobbler(process.getInputStream(), System.out::println);

Executors.newSingleThreadExecutor().submit(streamGobbler);

int exitCode = process.waitFor();
}

}

StreamGlobber 是一个天真的消费者:

    public class StreamGobbler implements Runnable {
private InputStream inputStream;
private Consumer<String> consumer;

public StreamGobbler(InputStream inputStream, Consumer<String> consumer) {
this.inputStream = inputStream;
this.consumer = consumer;
}

@Override
public void run() {
new BufferedReader(new InputStreamReader(inputStream)).lines().forEach(consumer);
}
}

有人可以告诉我我这里出了什么问题吗?

最佳答案

问题不在于处理外部进程,而是错误使用了 Executors.newSingleThreadExecutor() 返回的 ExecutorService。此方法创建一个在后台运行的线程,并且由于您从未关闭此执行器(这会停止该线程),因此此线程会阻止 JVM 退出。

如果您愿意,您可以通过添加一行打印其退出代码来证明 ls 进程已退出。但请注意,该行可能不会出现在输出的底部。

为了解决这个问题,我们需要保留对创建的 ExecutorService 的引用,然后在不再需要它时将其关闭。尝试更换

        Executors.newSingleThreadExecutor().submit(streamGobbler);

int exitCode = process.waitFor();

        ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(streamGobbler);

int exitCode = process.waitFor();

executor.shutdown();

我对您的代码进行了此更改,它从挂起变为干净退出。

关于java - ProcessBuilder waitFor() 永远不会返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46331729/

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