Java9 进程API详细详解
发布时间:2021-12-07 16:03:32 所属栏目:教程 来源:互联网
导读:官方在JEP 102中引进新的进程API来增强Java.lang.Process 类,并且引进java.lang.ProcessHandle 及其嵌套接口Info 来让开发者逃离时常因为要获取一个本地进程的PID而不得不使用本地代码的窘境。本文将详细介绍这些新特性。 1、ProcessHandle 与 ProcessHandl
PROCESS INFORMATION =================== Process id: 5516 Command: Arguments: Command line: Start time: 2017-03-02T22:24:41.763Z Run time duration: 234ms Owner: jeffjeffrey 第三部分的PROCESS INFORMATION迟迟没有出现,直到notepad界面消失才出现。Info的arguments() 方法没有向C:tempnames.txt 文件里打印命令行,可能是因为此时信息是不可用的,抑或是因为出现了bug。在进程结束之后,command()方法返回null。最后,当command()方法或者arguments() 方法其中之一返回了null,commandLine()方法也将返回null。 4、获取所有进程的信息 ProcessHandle 中的allProcesses() 方法以Java8中Stream API的方式返回当前系统中所有可见的进程句柄。下面的代码展示了如何使用Stream来获取进程句柄, 取前四个进程,dump出它们的信息。 import java.io.IOException; import java.time.Duration; import java.time.Instant; public class ProcessDemo { public static void main(String[] args) { ProcessHandle.allProcesses() .filter(ph -> ph.info().command().isPresent()) .limit(4) .forEach((process) -> dumpProcessInfo(process)); } static void dumpProcessInfo(ProcessHandle ph) { System.out.println("PROCESS INFORMATION"); System.out.println("==================="); System.out.printf("Process id: %d%n", ph.getPid()); ProcessHandle.Info info = ph.info(); System.out.printf("Command: %s%n", info.command().orElse("")); String[] args = info.arguments().orElse(new String[]{}); System.out.println("Arguments:"); for (String arg: args) System.out.printf(" %s%n", arg); System.out.printf("Command line: %s%n", info.commandLine().orElse("")); System.out.printf("Start time: %s%n", info.startInstant().orElse(Instant.now()).toString()); System.out.printf("Run time duration: %sms%n", info.totalCpuDuration() .orElse(Duration.ofMillis(0)).toMillis()); System.out.printf("Owner: %s%n", info.user().orElse("")); System.out.println(); } } main()方法中调用allProcesses()方法,从路径名显示地将线程句柄流链式导入到一个filter之后再包装到一个新的线程句柄流。 (在我的环境中,当进程终止之后就不会打印出路径) limit(4) 方法可以截取不超过4个进程来放入流中。最后,迭代出它们的所有信息。 以下是输出结果: PROCESS INFORMATION =================== Process id: 8036 Command: C:Windowsexplorer.exe Arguments: Command line: Start time: 2017-03-02T16:21:14.436Z Run time duration: 299328ms Owner: jeffjeffrey PROCESS INFORMATION =================== Process id: 10200 Command: C:WindowsSystem32dllhost.exe Arguments: Command line: Start time: 2017-03-02T16:21:16.255Z Run time duration: 2000ms Owner: jeffjeffrey PROCESS INFORMATION =================== Process id: 1544 Command: C:Program Files (x86)WNSSWNSS.exe Arguments: Command line: Start time: 2017-03-02T16:21:21.708Z Run time duration: 862375ms Owner: jeffjeffrey PROCESS INFORMATION =================== Process id: 8156 Command: C:UsersjeffreyAppDataLocalSweetLabs App PlatformEngineServiceHostAppUpdater.exe Arguments: Command line: Start time: 2017-03-02T16:21:24.302Z Run time duration: 2468ms Owner: jeffjeffrey ProcessHandle的 children() 方法和 descendents() 方法运行结果很像allProcesses() f方法,除了它们是否是静态方法,以及返回值类型不一样之外,它们之间有一个集合从属关系,children() 是descendents()的子集,descendents()是allProcesses()的子集。 5、进程终止的触发机制 最后, ProcessHandle的 onExit() 方法返回java.util.concurrent.CompletableFuture让进程在终止时进行同步或异步操作成为可能。 在一个进程终止的时候打印出它的PID: import java.io.IOException; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; public class ProcessDemo { public static void main(String[] args) throws ExecutionException, InterruptedException, IOException { Process p = new ProcessBuilder("notepad.exe").start(); ProcessHandle ph = p.toHandle(); CompletableFuture<ProcessHandle> onExit = ph.onExit(); onExit.get(); onExit.thenAccept(ph_ -> System.out.printf("PID %d terminated%n", ph_.getPid())); } } main() 方法首先创建了一个notepad.exe进程。随后,又获取了这个进程的句柄,用这个句柄又得到了CompletableFuture。onExit.get() 在 main()获取到进程终止信号后会进行一些操作。 PID 7460 terminated 6、结论 Java 9的 Process API 增强早就该和Java一起出现并受到欢迎。虽然这盘文章介绍了一些它的API,但是更多的还是需要你去探索,比如,supportsNormalTermination() 方法或者parent() 方法的用法等等。 ![]() (编辑:宿州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐