Java ProcessHandle简介

This is a quick introduction to application of Java ProcessHandle through a use case.

Background:

I developed a website call ps2pdf.com. It uses a range of free software to process user requests. To put it simply, it is an orchestrator for bunch of free opensource software such as FFMPEG. While there are libraries that allows me to use most of these software directly from my Java application (Mostly though JNI), they are always bit outdated or unstable. I, being a brave programmer, choose to use Java ProcessBuilder and Process to execute programs such as FFMPEG with arguments. Managing of processes spawn like that is bit chaotic. Until the release of Java 9, I had a code that mainly uses Runtime.getRuntime().exec("ps aux...") to find and kill processes that hangs or exceed time limit. I had quite a bit of code, an ugly code, written to manage processes. I got really exited when I came across Java 9 ProcessHandle interface. It exposes many information about processes running on a machine (specifically when used in Linux systems) which I could use to do a major cleanup.

About ProcessHandle:

Java ProcessHandle提供了本机进程的接口。 接口允许阅读信息关于流程的信息,例如检查某个流程是否处于活动状态或调用简单的操作在诸如杀死它的过程中。

Use case:

我将通过以下用例向您介绍,该用例曾用于解释ProcessHandle接口的一些有用部分。

  1. 获取系统上所有正在运行的进程Filter ffmpeg processes that meets a certain criteria检查它们是否正在运行检查它们是否正在运行 for more than 4 hours检查输入到ffmpeg的输入文件是否已删除杀死所有挂起的ffmpeg进程
Step 1: Finding all processes
Stream<ProcessHandle> allProcesses = ProcessHandle.allProcesses();
Step 2: Filter processes
Stream<ProcessHandle> toDeleteProcessHandles = allProcesses.filter(processHandle -> {
    // Check if process is alive
    if(processHandle.isAlive()){
        Info info = processHandle.info();
        String executableWithPath = info.command().orElse(null);
        // Check if this is an ffmpeg instant
        if(executableWithPath != null && executableWithPath.endsWith("ffmpeg")){
            // Check if they are running for more than 4 hours
            if(Duration.between(Instant.now(), info.startInstant().get()).toHours() > 4){

                // Check if input file fed on to ffmpeg is deleted
                String[] arguments = info.arguments().orElse(null);
                String inputFile = Arrays.stream(arguments).filter(arg -> arg.startsWith("/home/username/content/input")).findFirst().orElse(null);
                if(inputFile != null && !Files.exists(Paths.get(inputFile))){
                    return true;
                }
            }
        }
    }
    return false;
});
Step 3: Kill hanged processes
toDeleteProcessHandles.forEach(processHandle -> processHandle.destroy());

This interface combined with Stream API allow writing concise code. You may have noticed that I used orElse(null) in some places. Which is from Java Optional class introduced in Java 1.8 with Stream API. You can further clean up this code by using methods such is isPresent() on Optional class instead of clustering with someVariable != null && doSomethingWithSomeVariable inside if expressions checks.

这个类的另一个有用的静态方法是

ProcessHandle handle = ProcessHandle.of(long pid);

当您使用ProcessBuilder启动流程或具有Java Process对象时,这很有用。 尽管Java Process对象(Java 9+)公开了进程的PIDsomeProcess.pid()。 您可以使用的ProcessHandle.of()跟踪过程。

You could find more about ProcessHandle and ProcessHandle.Info by reading their documentation.

This very code is in action every time someone convert a video or compresses a jpeg on PDF2PDF.

感谢您的阅读。 欢迎您提出问题或提出反馈。

from: https://dev.to//harithay/introduction-to-java-processhandle-5950

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值