本文主要研究下JEP 102: Process API Updateshtml
/Library/Java/JavaVirtualMachines/jdk-9.0.4.jdk/Contents/Home/lib/src.zip!/java.base/java/lang/ProcessHandle.javajava
java9新引入了ProcessHandle
/** * ProcessHandle identifies and provides control of native processes. Each * individual process can be monitored for liveness, list its children, * get information about the process or destroy it. * By comparison, {@link java.lang.Process Process} instances were started * by the current process and additionally provide access to the process * input, output, and error streams. * <p> * The native process ID is an identification number that the * operating system assigns to the process. * The range for process id values is dependent on the operating system. * For example, an embedded system might use a 16-bit value. * Status information about a process is retrieved from the native system * and may change asynchronously; processes may be created or terminate * spontaneously. * The time between when a process terminates and the process id * is reused for a new process is unpredictable. * Race conditions can exist between checking the status of a process and * acting upon it. When using ProcessHandles avoid assumptions * about the liveness or identity of the underlying process. * <p> * Each ProcessHandle identifies and allows control of a process in the native * system. ProcessHandles are returned from the factory methods {@link #current()}, * {@link #of(long)}, * {@link #children}, {@link #descendants}, {@link #parent()} and * {@link #allProcesses()}. * <p> * The {@link Process} instances created by {@link ProcessBuilder} can be queried * for a ProcessHandle that provides information about the Process. * ProcessHandle references should not be freely distributed. * * <p> * A {@link java.util.concurrent.CompletableFuture} available from {@link #onExit} * can be used to wait for process termination, and possibly trigger dependent * actions. * <p> * The factory methods limit access to ProcessHandles using the * SecurityManager checking the {@link RuntimePermission RuntimePermission("manageProcess")}. * The ability to control processes is also restricted by the native system, * ProcessHandle provides no more access to, or control over, the native process * than would be allowed by a native application. * * @implSpec * In the case where ProcessHandles cannot be supported then the factory * methods must consistently throw {@link java.lang.UnsupportedOperationException}. * The methods of this class throw {@link java.lang.UnsupportedOperationException} * if the operating system does not allow access to query or kill a process. * * <p> * The {@code ProcessHandle} static factory methods return instances that are * <a href="{@docRoot}/java/lang/doc-files/ValueBased.html">value-based</a>, * immutable and thread-safe. * Use of identity-sensitive operations (including reference equality * ({@code ==}), identity hash code, or synchronization) on these instances of * {@code ProcessHandle} may have unpredictable results and should be avoided. * Use {@link #equals(Object) equals} or * {@link #compareTo(ProcessHandle) compareTo} methods to compare ProcessHandles. * * @see Process * @since 9 */ public interface ProcessHandle extends Comparable<ProcessHandle> { //... }
ProcessHandle提供了對本地進程的控制,能夠監控其存活,查找其子進程,查看其信息,甚至銷燬它。很是適合耗時較長的進程調用。
@Test public void testProcessHandle() { final ProcessHandle processHandle = ProcessHandle.current(); final ProcessHandle.Info info = processHandle.info(); System.out.println("Process info =>"); System.out.format("PID: %s%n", processHandle.pid()); info.arguments().ifPresent(args -> System.out.format("Arguments: %s%n", Arrays.toString(args))); info.command().ifPresent(command -> System.out.format("Command: %s%n", command)); info.commandLine() .ifPresent(commandLine -> System.out.format("Command line: %s%n", commandLine)); info.startInstant() .ifPresent(startInstant -> System.out.format("Start time: %s%n", startInstant)); info.totalCpuDuration() .ifPresent(cpuDuration -> System.out.format("CPU time: %s%n", cpuDuration)); info.user().ifPresent(user -> System.out.format("User: %s%n", user)); }
@Test public void testControlProcess() throws IOException { final ProcessBuilder processBuilder = new ProcessBuilder("top") .inheritIO(); ProcessHandle processHandle = processBuilder.start().toHandle(); final CountDownLatch latch = new CountDownLatch(1); processHandle.onExit().whenCompleteAsync((handle, throwable) -> { if (throwable == null) { System.out.println(handle.pid()); } else { throwable.printStackTrace(); } latch.countDown(); }); final Thread shutdownThread = new Thread(() -> { try { Thread.sleep(1000); } catch (final InterruptedException e) { e.printStackTrace(); } if (processHandle.supportsNormalTermination()) { processHandle.destroy(); } else { processHandle.destroyForcibly(); } }); shutdownThread.start(); try { shutdownThread.join(); latch.await(); } catch (final InterruptedException e) { e.printStackTrace(); } }
java9對process api的最大的更新就是引進了ProcessHandle,能夠用來查看進程信息,監控並銷燬它。git