You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java中列出JVM中的所有虚拟线程?

如何列出JVM中的所有虚拟线程?

传统的线程枚举方法(如ThreadMXBean.dumpAllThreads()、ThreadMXBean.getAllThreadIds()、ThreadGroup.enumerate()和Thread.getAllStackTraces())仅能识别平台线程(Platform Thread),虚拟线程不会被这些方法返回——因为它们不属于传统的ThreadGroup体系,也未被MXBean纳入统计范围。以下是几种可行的解决方案:

1. 使用Java 21+ 标准API(推荐)

Java 21正式引入了Thread.getAllThreads()方法,该方法会返回JVM中所有线程,包括虚拟线程和平台线程。你可以通过Thread.isVirtual()方法区分两者:

import java.util.Arrays;

public class ListAllThreads {
    public static void main(String[] args) {
        // 示例:创建一个虚拟线程
        Thread virtualThread = Thread.ofVirtual().start(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        // 获取所有线程并筛选虚拟线程
        Thread[] allThreads = Thread.getAllThreads();
        System.out.println("JVM中的所有虚拟线程:");
        Arrays.stream(allThreads)
              .filter(Thread::isVirtual)
              .forEach(t -> System.out.printf("线程ID: %d, 名称: %s%n", t.threadId(), t.getName()));
    }
}

2. Java 19/20 预览版临时方案(不推荐生产环境)

在虚拟线程处于预览阶段的Java 19和20中,没有公开的标准API枚举所有虚拟线程,但可以通过JDK内部APIjdk.internal.vm.VirtualThreads实现注意:内部API可能在未来版本变更,生产环境禁止使用:

import jdk.internal.vm.VirtualThreads;
import java.util.List;

public class ListVirtualThreadsPreview {
    public static void main(String[] args) {
        Thread virtualThread = Thread.ofVirtual().start(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        // 调用内部API获取所有虚拟线程
        List<Thread> virtualThreads = VirtualThreads.listVirtualThreads();
        System.out.println("JVM中的所有虚拟线程:");
        virtualThreads.forEach(t -> System.out.printf("线程ID: %d, 名称: %s%n", t.threadId(), t.getName()));
    }
}

编译运行时需要添加参数允许访问内部API:--add-exports java.base/jdk.internal.vm=ALL-UNNAMED

3. 自定义跟踪虚拟线程(可控场景)

如果仅需要跟踪自己应用创建的虚拟线程,可以维护一个线程集合,在创建虚拟线程时加入,结束时移除:

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

public class TrackVirtualThreads {
    private static final Set<Thread> VIRTUAL_THREADS = Collections.synchronizedSet(new HashSet<>());

    // 封装虚拟线程创建逻辑,自动跟踪
    public static Thread createVirtualThread(Runnable task) {
        Thread vt = Thread.ofVirtual().start(() -> {
            try {
                task.run();
            } finally {
                VIRTUAL_THREADS.remove(vt);
            }
        });
        VIRTUAL_THREADS.add(vt);
        return vt;
    }

    public static void main(String[] args) {
        createVirtualThread(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        System.out.println("当前跟踪的虚拟线程:");
        VIRTUAL_THREADS.forEach(t -> System.out.printf("线程ID: %d, 名称: %s%n", t.threadId(), t.getName()));
    }
}

这种方式不受JVM版本限制,但仅能跟踪自己创建的虚拟线程,无法获取其他类库或框架创建的实例。

内容的提问来源于stack exchange,提问作者Nathan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 00:29:55