如何在Java程序中获取自己的进程号

Posted by Jeremy Song on 2021-08-17
Estimated Reading Time 5 Minutes
Words 1.4k In Total
Viewed Times

在分布式系统中,对于一个需要全局唯一ID的需求,我们可能会按照如下的格式来定一个ID的组成:

机器编号 + 进程号 + 时间戳 + 流水号

按照上面这个逻辑,我们可能会得到一个类似 08C5 00375 20210320232030 0001 这样的ID。

当然根据您的业务实际情况,这个ID的规则可能会有很多变种。比如去掉空格、加上业务标志符、时间戳到毫秒、时间戳到日期、每个部分用不同的符号分隔等等,这些当然都是可以的。但是仔细一想好像哪里不对劲,我怎么获取自己正在运行的进程号呢?

不过,如果您不存在一个机器或容器里面运行多个相同业务实例的话,那肯定可以不用进程号来区分了。这个就属于本篇文章之外的情况,咱们暂不考虑。下面就来说明如何在运行的过程中获取自己的进程号。

获取Java进程自己的进程号

从JDK 1.5开始,软件包 java.lang.management 提供了管理接口,用于监视和管理 Java 虚拟机以及 Java 虚拟机在其上运行的操作系统。它同时允许从本地和远程对正在运行的 Java 虚拟机进行监视和管理。

其中 java.lang.management.RuntimeMXBean 为Java 虚拟机的运行时系统的管理接口。
Java 虚拟机具有此接口的实现类的单一实例。实现此接口的实例是一个 MXBean,它可以通过调用 ManagementFactory.getRuntimeMXBean() 方法或从平台 MBeanServer 方法获得。

因为我们可以通过 RuntimeMXbean 对象来获取当前运行时的信息,自然也就可以获取到自己的进程号了。请看如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
import java.lang.management.ManagementFactory;

public class PIDSelector {

public static void main(String[] args) {
String name = ManagementFactory.getRuntimeMXBean().getName();
System.out.println(name);

String pid = name.split("@")[0];
System.out.println("Pid is:" + pid);
}
}

运行上面的代码,输出结果为:

1
2
13904@msi
Pid is:13904

这样我们就得到了当前运行中进程自己的进程号。

PS:顺便提一句,一般ID都需要有固定的位数,所以涉及到序列号格式化的问题。因为在Windows(x86/64)、Linux/Unix(x86/x64)等其他不同平台上进程号的最大值是不一样的。您如果需要格式化进程号,最好是调研一下您的运行平台的最大进程号是多少,以免出现溢出或反转的问题。

扩展

java.lang.management.ManagementFactory

ManagementFactory 类是一种工厂类,用于获取 Java 平台的管理 Bean。此类由静态方法组成,每种静态方法都会返回一个或多个表示 Java 虚拟机组件的管理接口的平台 MXBean。应用程序可以采用以下方式访问平台 MXBean:

  1. 直接访问 MXBean 接口
    • 通过静态工厂方法获取 MXBean 实例,从本地访问正在运行的虚拟机的 MXBean。
    • 构造一个 MXBean 代理实例,以通过调用 newPlatfromMXBeanProxy 将方法调用转发到给定的 MBeanServer。构造代理通常是为了远程访问另一个正在运行的虚拟机的 MXBean。
  2. 通过 MBeanServer 间接地访问 MXBean 接口
    • 通过平台 MBeanServer 本地访问 MXBean 或通过特定的 MBeanServerConnection 远程访问 MXBean

ManagementFactory 静态方法摘要

方法名 说明
getClassLoadingMXBean() 返回 Java 虚拟机的类加载系统的管理 Bean。
getCompilationMXBean() 返回 Java 虚拟机的编译系统的管理 Bean。
getGarbageCollectorMXBeans() 返回 Java 虚拟机中的 GarbageCollectorMXBean 对象列表。
getMemoryManagerMXBeans() 返回 Java 虚拟机中的 MemoryManagerMXBean 对象列表。
getMemoryMXBean() 返回 Java 虚拟机的内存系统的管理 Bean。
getMemoryPoolMXBeans() 返回 Java 虚拟机中的 MemoryPoolMXBean 对象列表。
getOperatingSystemMXBean() 返回运行 Java 虚拟机的操作系统的管理 Bean。
getPlatformMBeanServer() 返回平台 MBeanServer。
getRuntimeMXBean() 返回 Java 虚拟机的运行时系统的管理 Bean。
getThreadMXBean() 返回 Java 虚拟机的线程系统的管理 Bean。
newPlatformMXBeanProxy(MBeanServerConnection connection, String mxbeanName, Class<T> mxbeanInterface) 返回用于给定 MXBean 名称的平台 MXBean 接口的代理,以便通过给定 MBeanServerConnection 转发其方法调用。

java.lang.management.RuntimeMXBean

RuntimeMXBean 类我们在上面已经介绍了,它为Java 虚拟机的运行时系统的管理接口。下面介绍一下方法摘要:

方法名 说明
getBootClassPath() 返回由引导类加载器用于搜索类文件的引导类路径。
getClassPath() 返回系统类加载器用于搜索类文件的 Java 类路径。
getInputArguments() 返回传递给 Java 虚拟机的输入变量,其中不包括传递给 main 方法的变量。
getLibraryPath() 返回 Java 库路径。
getManagementSpecVersion() 返回正在运行的 Java 虚拟机实现的管理接口的规范版本。
getName() 返回表示正在运行的 Java 虚拟机的名称。
getSpecName() 返回 Java 虚拟机规范名称。
getSpecVendor() 返回 Java 虚拟机规范供应商。
getSpecVersion() 返回 Java 虚拟机规范版本。
getStartTime() 返回 Java 虚拟机的启动时间(以毫秒为单位)。
getSystemProperties() 返回所有系统属性的名称和值的映射。
getUptime() 返回 Java 虚拟机的正常运行时间(以毫秒为单位)。
getVmName() 返回 Java 虚拟机实现名称。
getVmVendor() 返回 Java 虚拟机实现供应商。
getVmVersion() 返回 Java 虚拟机实现版本。
isBootClassPathSupported() 测试 Java 虚拟机是否支持由引导类加载器用于搜索类文件的引导类路径机制。

欢迎关注我的公众号 须弥零一,跟我一起学习IT知识。


如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。 也欢迎您共享此博客,以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。 谢谢 !