Start, stop and listen to a process in Java

2019-09-01 06:28发布

I want to start a process with Runtime.exec(). Then I want to know (listen) when the process exits. Also, I want to manually stop the process if some condition met.

The code I have now is:

public class ProcessManager extends Thread{
    private static ProcessManager manager;

    Process process;

    private ProcessManager(){

    }

    public static ProcessManager getInstance(){
        if(manager==null){
            manager=new ProcessManager();
        }
        return manager;
    }

    public void run(){
        Runtime runtime = Runtime.getRuntime();
        process = runtime.exec("c:\\windows\\system32\\notepad.exe");
        //cleanup();
    }
    public void cleanup(){
        //I want to do stuffs until the program really ends;
    }

    //called to manually stop the process
    public void stopProcess(){
        if(process!=null){
            //TODO: stop the process;
        }
    }
}

As shown in the code, my program is like notepad.exe, which pop up a window and immediately returns. How can I listen to the status of the program, and wait until it is closed, as well as close it explicitly?

2条回答
你好瞎i
2楼-- · 2019-09-01 07:17

I would not recommend using Runtime.exec() directly. It is not as straightforward as it might seem. Nice article "When Runtime.exec() won't" describes these pitfalls in details. For example simple code with waitFor():

Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("javac");
int exitVal = proc.waitFor();
System.out.println("Process exitValue: " + exitVal);

will produce no output and hangs, because in general you need to provide handling of input, output and error streams in separate threads.

Instead you may use Apache Commons Exec library that will handle it for you:

String line = "notepad.exe";
CommandLine cmdLine = CommandLine.parse(line);
DefaultExecutor executor = new DefaultExecutor();
int exitValue = executor.execute(cmdLine);
System.out.println("Process exitValue: " + exitValue);

Below is more complex example of asynchronous process terminated manually:

String line = "notepad.exe";
CommandLine cmdLine = CommandLine.parse(line);
ExecuteWatchdog watchdog = new ExecuteWatchdog(timeout);
Executor exec = new DefaultExecutor();
DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler();
exec.execute(cmdLine, handler);
// wait for script to run
Thread.sleep(2000);
// terminate it manually if needed
if (someCondition) {
    watchdog.destroyProcess();
}
// wait until the result of the process execution is propagated
handler.waitFor(WAITFOR_TIMEOUT);
System.out.println("Process exitValue: " + handler.getExitValue());
查看更多
女痞
3楼-- · 2019-09-01 07:22

How can I listen to the status of the program, and wait until it is closed, as well as close it explicitly?

You can use Process#waitFor()

// cause this process to stop until process p is terminated
         p.waitFor();

As JavaDoc says

The java.lang.Process.waitFor() method causes the current thread to wait, if necessary, until the process represented by this Process object has terminated. This method returns immediately if the subprocess has already terminated. If the subprocess has not yet terminated, the calling thread will be blocked until the subprocess exits.

查看更多
登录 后发表回答