Java Stop Process and Close Streams

2019-07-08 16:07发布

问题:

I'm using ProcessBuilder to launch an external process, but I need to be able to kill it. Right now I have no problem killing the process but for some reason the error stream doesn't close so the thread reading the stream never finishes. This keeps me from closing my program.

Here's where I start the threads reading from the input and error streams.

                final Thread inputPrinter = new Thread() {
                    public void run() {
                        BufferedReader inputStream = new BufferedReader(new InputStreamReader(builder.getInputStream()));
                        String line;
                        try {
                            while ((line = inputStream.readLine()) != null) {
                                Util.println(line, false);
                            }
                        } catch (IOException e) {
                        } finally {
                            Util.println("input end");
                            try {
                                inputStream.close();
                            } catch (IOException e) {
                            }
                        }
                    }
                };
                inputPrinter.start();

                Thread errorPrinter = new Thread() {
                    public void run() {
                        BufferedReader errorStream = new BufferedReader(new InputStreamReader(builder.getErrorStream()));
                        String line;
                        try {
                            while ((line = errorStream.readLine()) != null) {
                                Util.println(line, true);
                            }
                        } catch (IOException e) {
                        } finally {
                            Util.println("error end");
                            try {
                                errorStream.close();
                            } catch (IOException e) {
                            }
                        }
                    }
                };
                errorPrinter.start();
                builder.waitFor();

                Util.println("");
                Util.println("Finished building project.");

Here's my code for stopping the process.

        try {
            builder.getOutputStream().close();
            builder.getInputStream().close();
            builder.getErrorStream().close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        builder.destroy();
        Util.println("");
        Util.println("Build aborted by user.", true);

When I try to stop the process I get the following printed.

Build aborted by user.

Finished building project.

input end

I never get "error end" and debugging the program shows the thread is just sitting at "readLine()".

The code that waits for the process is running in it's own thread (separate from the code that kills the process).

What do I need to do to make sure that the errorPrinter thread dies?

回答1:

I had the same problem,i use a speechRecognizer,so i am running a separate Thread which is running another .jar which prints to console and read the output using BufferedReader(something like this..):

//In seperate Thread from the Main App Thread
while (!stopped) {
                while ((line = bufferedReader.readLine()) != null && !line.isEmpty()) {
                    System.out.println(line);
                    checkSpeechResult(line);
                }
            }

The problem

Basically the bufferedRead.readLine() lags until it has something to read.

If nothing comes it will wait forever.

Answer:

From another Thread call this:

process.destroy();

and it will stop the process so the bufferedRead.readLine() will exit.