序
本文主要研究下JEP 102: Process API Updates
ProcessHandle
/Library/Java/JavaVirtualMachines/jdk-9.0.4.jdk/Contents/Home/lib/src.zip!/java.base/java/lang/ProcessHandle.java
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,可以用来查看进程信息,监控并销毁它。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。