Java9 进程API

来源:互联网 发布:office mac 破解 威锋 编辑:程序博客网 时间:2024/06/05 18:59

1. 概述

Java中的进程API在Java5之前还是非常原始的,开启一个新进程唯一的方式是调用Runtime.getRuntime().exec() ,直到Java5发布之后,一些更加简明的开启新进程方式被封装到了ProcessBuilder 中。

而在Java9中,你也将能使用一种全新的方式来获取当前系统所有正在运行的进程的相关信息。

话不多说,先睹为快!

2. 当前Java进程的信息

我们通过调用java.lang.ProcessHandle.Info 可以获取诸多进程的相关信息:

  • 用于开启此进程所使用的命令
  • 命令中传递的参数
  • 开启时间
  • 开启者和总运行时间

下面是具体方式:

@Testpublic void givenCurrentProcess_whenInvokeGetInfo_thenSuccess()   throws IOException {    ProcessHandle processHandle = ProcessHandle.current();    ProcessHandle.Info processInfo = processHandle.info();    assertNotNull(processHandle.getPid());    assertEquals(false, processInfo.arguments().isPresent());    assertEquals(true, processInfo.command().isPresent());    assertTrue(processInfo.command().get().contains("java"));    assertEquals(true, processInfo.startInstant().isPresent());    assertEquals(true,       processInfo.totalCpuDuration().isPresent());    assertEquals(true, processInfo.user().isPresent());}

需要注意的是,java.lang.ProcessHandle.Info 是在另一个接口java.lang.ProcessHandle中定义的公共接口。JDK 供应商(Oracle JDK, Open JDK, Zulu 或其他) 以上面这些方式来为接口提供实现,以使它们能返回进程的相关信息。

3. 产生进程的信息

我们也可以获取新产生的进程的相关信息。在此情况下,在我们调用java.lang.Process生成并获取一个进程之后,我们调用toHandle()方法来获取java.lang.ProcessHandle的实例。

其他细节与上例一致:

String javaCmd = ProcessUtils.getJavaCmd().getAbsolutePath();ProcessBuilder processBuilder = new ProcessBuilder(javaCmd, "-version");Process process = processBuilder.inheritIO().start();ProcessHandle processHandle = process.toHandle();

4. 枚举系统中的实时进程

我们可以列举出当前系统中的所有进程,这些进程对当前进程可见。返回的列表是调用API时的快照,因此在操作的同时可能有进程终止,也可能有新的进程被开启。

我们可以使用java.lang.ProcessHandle 接口中声明的静态方法allProcesses() 来获取ProcessHandle 流:

@Testpublic void givenLiveProcesses_whenInvokeGetInfo_thenSuccess() {    Stream<ProcessHandle> liveProcesses = ProcessHandle.allProcesses();    liveProcesses.filter(ProcessHandle::isAlive)      .forEach(ph -> {        assertNotNull(ph.getPid());        assertEquals(true, ph.info()          .command()          .isPresent());      });}

5. 枚举子进程

这里有两种获取方式:

  • 获取当前进程的直属子级
  • 获取当前进程的所有子级

前者调用children() ,后者调用descendants()

@Testpublic void givenProcess_whenGetChildProcess_thenSuccess()   throws IOException{    int childProcessCount = 5;    for (int i = 0; i < childProcessCount; i++){        String javaCmd = ProcessUtils.getJavaCmd()          .getAbsolutePath();        ProcessBuilder processBuilder           = new ProcessBuilder(javaCmd, "-version");        processBuilder.inheritIO().start();    }    Stream<ProcessHandle> children      = ProcessHandle.current().children();    children.filter(ProcessHandle::isAlive)      .forEach(ph -> log.info("PID: {}, Cmd: {}",        ph.getPid(), ph.info().command()));    // and for descendants    Stream<ProcessHandle> descendants      = ProcessHandle.current().descendants();    descendants.filter(ProcessHandle::isAlive)      .forEach(ph -> log.info("PID: {}, Cmd: {}",        ph.getPid(), ph.info().command()));}

6. 进程终止时触发相关操作

有时候有需求需要我们在某个进程终止时触发某些操作,我们可以通过调用java.lang.ProcessHandle 接口中声明的onExit() 方法来满足。 该方法返回CompletableFuture,可以在CompletableFuture完成时触发某些操作。

CompletableFuture 表示一个进程已经完成,它不关心进程以何种方式完成。通过显式调用它的get() 方法来等待进程完成:

@Testpublic void givenProcess_whenAddExitCallback_thenSuccess()   throws Exception {    String javaCmd = ProcessUtils.getJavaCmd()      .getAbsolutePath();    ProcessBuilder processBuilder       = new ProcessBuilder(javaCmd, "-version");    Process process = processBuilder.inheritIO()      .start();    ProcessHandle processHandle = process.toHandle();    log.info("PID: {} has started", processHandle.getPid());    CompletableFuture<ProcessHandle> onProcessExit       = processHandle.onExit();    onProcessExit.get();    assertEquals(false, processHandle.isAlive());    onProcessExit.thenAccept(ph -> {        log.info("PID: {} has stopped", ph.getPid());    });}

当然,也可以通过java.lang.Process 接口来调用onExit()方法。

原文:http://www.baeldung.com/java-9-process-api

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 10个月宝宝还没长牙怎么办 超敏c反应蛋白>5怎么办 怀孕才两个月肚子就大了怎么办 腰椎间盘突出腿疼厉害怎么办 打了促排卵针不排卵怎么办 孕34周隐血1十是怎么办 窦性心动过缓伴不齐怎么办 09年买的万科b怎么办 苹果5s手机打不开机怎么办 剖腹产后一年半后意外怀孕怎么办 考驾照挂了5次了怎么办 怀孕咳嗽一个月了好不了怎么办 孕妇餐后2小时血糖高怎么办 我想开网店但我不懂该怎么办 新开的淘宝店没生意怎么办 做肝胆b超喝了水怎么办 红米1s刷机失败怎么办 红米3x手机太卡怎么办 红米2a线刷失败怎么办 红米2用不了4g怎么办 小米红米3s卡顿怎么办 魅蓝4g网速很慢怎么办 lol装到c盘了会怎么办 急用钱又借不到怎么办小额信贷 花呗分期买手机额度不够怎么办 2个月婴儿脸皴了怎么办 掉头发怎么办怎样能让头发变多 11个月的宝宝大便干燥怎么办 1岁宝宝又拉又吐怎么办 怀孕八个月了不想要了怎么办 奶水不够宝宝又不喝奶粉怎么办 手机恢复出厂设置密码忘了怎么办 5s锁屏密码忘了怎么办 深圳房子卖了户口没地方迁怎么办 宝马1系130i烧机怎么办 小孩流清鼻涕怎么办最简单方法 孕3个月胎盘低置怎么办 孩子判逆不听家长的话该怎么办 香港购物超5000被海关扣怎么办 浅色衣服被深色衣服染色了怎么办 金立手机微信不能发语音怎么办