1. 概述

在这个简短的教程中,我们将学习如何获取当前JVM中所有正在运行的线程,包括不是由我们类启动的线程。

2. 使用Thread

Thread类的getAllStackTrace()方法提供了所有运行线程的堆栈跟踪。它返回一个Map,其中的键是Thread对象,我们可以获取键集并遍历元素来获取有关线程的信息。

让我们使用printf()方法使输出更易读:

Set<Thread> threads = Thread.getAllStackTraces().keySet();
System.out.printf("%-15s \t %-15s \t %-15s \t %s\n", "Name", "State", "Priority", "isDaemon");
for (Thread t : threads) {
    System.out.printf("%-15s \t %-15s \t %-15d \t %s\n", t.getName(), t.getState(), t.getPriority(), t.isDaemon());
}

输出将如下所示:

Name                 State                Priority             isDaemon
main                 RUNNABLE             5                    false
Signal Dispatcher      RUNNABLE             9                    true
Finalizer            WAITING              8                    true
Reference Handler      WAITING              10                   true

如我们所见,除了运行主程序的主线程外,还有其他三个线程。这个结果可能会因不同的Java版本而变化。

让我们进一步了解这些其他线程:

  • 信号分发器:处理操作系统发送给JVM的信号。
  • 终结器:为不再需要释放系统资源的对象执行清理操作。
  • 引用处理器:将不再需要的对象放入队列,供终结器线程处理。

如果主程序退出,所有这些线程都将终止。

3. 使用Apache Commons的ThreadUtils

我们还可以使用Apache Commons Lang库中的ThreadUtils类来实现相同的目标:

pom.xml文件中添加依赖:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.14.0</version>
</dependency>

然后简单地使用getAllThreads()方法获取所有运行线程:

System.out.printf("%-15s \t %-15s \t %-15s \t %s\n", "Name", "State", "Priority", "isDaemon");
for (Thread t : ThreadUtils.getAllThreads()) {
    System.out.printf("%-15s \t %-15s \t %-15d \t %s\n", t.getName(), t.getState(), t.getPriority(), t.isDaemon());
}

输出与上述相同。

4. 总结

总之,我们学习了两种方法来获取当前JVM中所有正在运行的线程