Java运行异步进程

Sar*_*aya 6 java multithreading asynchronous process processbuilder

我正在尝试运行异步进程,我不希望程序等到这些进程执行结束.我发现这个问题如何从Java程序中异步运行shell脚本,但它没有我想要的答案.

我正在做的是我只是运行bash进程,运行之后,我不希望Java程序等到它完成.这就是我所做的:

public void runCommandLine(String directory) throws IOException {
    Thread commandLineThread = new Thread(() -> {
        try {
            ProcessBuilder processBuilder = new ProcessBuilder(
                    "/bin/bash");
            processBuilder.directory(new File(directory));
            Process process = processBuilder.start();
            try (OutputStreamWriter osw = new OutputStreamWriter(process.getOutputStream())) {
                osw.write(command);
            }
            printStream(process.getErrorStream(), true);
            printStream(process.getInputStream(), true);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    });
    commandLineThread.start();
    System.out.println("Task Dispatched");
}
Run Code Online (Sandbox Code Playgroud)

我还在main方法的末尾添加了另一个打印输出,所以我得到了这个输出:

Task Dispatched
Task Dispatched
End of psvm
Run Code Online (Sandbox Code Playgroud)

但是,由于这两个进程尚未终止,程序不会终止.

我该如何解决这个问题?

K E*_*son 5

您需要使您的线程成为守护程序线程.setDaemon(true)在开始之前使用.

 commandLineThread.setDaemon(true);
Run Code Online (Sandbox Code Playgroud)

守护程序线程是一个不阻止JVM退出的线程.看到这个问题:Java中的守护程序线程是什么?有关守护程序线程的更多信息.

编辑:

通过判断您的注释,即使JVM即将退出,您也需要运行该命令.我假设command变量包含您要运行的脚本?您可以进行两项更改,以使程序按照我的意愿运行.

  1. 启动bash with -c来执行命令,然后您不必将内容发送到输出流.
  2. 在启动等待输出的线程之前启动该过程.

生成的代码看起来像:

public void runCommandLine(String directory) throws IOException {
    ProcessBuilder processBuilder = new ProcessBuilder(
                    "/bin/bash -c " + command);
    processBuilder.directory(new File(directory));
    Process process = processBuilder.start();
    Thread commandLineThread = new Thread(() -> {
        try {
            printStream(process.getErrorStream(), true);
            printStream(process.getInputStream(), true);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    });
    commandLineThread.setDaemon(true);
    commandLineThread.start();
    System.out.println("Task Dispatched");
}
Run Code Online (Sandbox Code Playgroud)