Java 9 brings various improvements to the Process API, used for controlling and managing operating system processes.
Getting information about a process
There is a new ProcessHandle
class which provides the process's pid, parent and descendants, as well as information about the start time and accumulated CPU time.
jshell> Process p = new ProcessBuilder("stress", "--cpu", "4", "--timeout", "5").start(); p ==> Process[pid=5572, exitValue="not exited"] jshell> p.pid() $2 ==> 5572 jshell> p.info().user() $3 ==> Optional[fahd] jshell> p.info().command() $4 ==> Optional[/usr/bin/stress] jshell> p.info().commandLine() $5 ==> Optional[/usr/bin/stress --cpu 4 --timeout 120] jshell> Arrays.toString(p.info().arguments().get()) $6 ==> "[--cpu, 4, --timeout, 120]" jshell> p.info().startInstant() $7 ==> Optional[2018-02-25T16:38:56.742Z] jshell> p.info().totalCpuDuration().get().toMillis() $8 ==> 0
It's strange that totalCpuDuration
always returns 0 (a duration string of "PT0S"), no matter what command I run.
Note that I am invoking the Linux stress
command in the example above. This is a useful tool for imposing a certain type of stress (e.g. creating cpu load) on your system.
Listing all running processes
The static ProcessHandle.allProcesses()
method returns a stream of all processes visible to the current process.
ProcessHandle.allProcesses() .map(ProcessHandle::info) .map(ProcessHandle.Info::commandLine) .flatMap(Optional::stream) .forEach(System.out::println)
Triggering a function when a process exits
The Process.onExit
method can be used to schedule a function when a process terminates. This method returns a CompletableFuture
, which contains a variety of methods that can be called to schedule functions. Here is an example:
Process proc = new ProcessBuilder("sleep", "10").start(); proc.onExit() .thenAccept(p -> System.out.println("Process " + p.pid() + " exited with " + p.exitValue()));
Alternatively, to wait for a process to terminate, you can call Process.onExit().get()
.