Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

multithreading - Java run async processes

I am trying to run an async process and I do not want the program to wait until the end of these processes executions. I found this question how to run shell script asynchronously from within Java program but it doesn't have the answer that I am looking for.

What I am doing is I am simply running bash processes and after I run it, I do not want the Java program to wait until it's finished. This is what I have done:

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");
}

I also put another print out at the end of the main method so I get this output:

Task Dispatched
Task Dispatched
End of psvm

However the program does not terminate as these two processes have not terminated.

How can I solve this issue?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You need to make your thread a daemon thread. Use setDaemon(true) before starting it.

 commandLineThread.setDaemon(true);

A daemon thread is a thread that does not prevent the JVM from exiting. See this question: What is Daemon thread in Java? for more information about daemon threads.

Edit:

By judging from your comments you need the command to run even though the JVM is about to exit. I assume the command variable contains the script you want to run? You could make two changes to make the program behave as I think you want.

  1. Start bash with -c to execute your command, then you do not have to send things to an output stream.
  2. Start the process before starting your thread that waits for the output.

The resulting code would look something like:

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");
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...