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

JDK 21中jdk.VirtualThreadPinned事件未触发的问题求助

排查jdk.VirtualThreadPinned事件未触发的可能原因

1. 事件未通过JVM参数或API启用

jdk.VirtualThreadPinned属于JDK Flight Recorder(JFR)事件,默认处于禁用状态,必须主动启用:

  • 启动测试时添加JVM参数,直接指定启用该事件:
    -XX:StartFlightRecording=events=jdk.VirtualThreadPinned
    
    或使用预设配置文件(profile配置默认包含该事件):
    -XX:StartFlightRecording=settings=profile,filename=test-recording.jfr
    
  • 也可以在代码中通过JFR API动态启用:
    EventType pinnedEventType = EventType.getEventType("jdk.VirtualThreadPinned");
    if (pinnedEventType != null) {
        pinnedEventType.setEnabled(true);
    }
    

2. 同步块执行时间未达触发阈值

JVM不会对短暂持有锁的虚拟线程触发固定事件,默认阈值为20毫秒(可通过-Djdk.virtualThread.pinned.threshold=xxx调整)。如果你的测试同步块执行太快,比如空块或瞬时操作,不会触发事件。可以在同步块中添加延迟:

synchronized (lockObj) {
    Thread.sleep(50); // 超过默认阈值,确保触发判定
}

3. 事件监听逻辑存在疏漏

检查自定义监听器是否正确绑定到jdk.VirtualThreadPinned事件:

  • 确认事件名称拼写完全正确,监听器注册时机早于虚拟线程执行:
    try (Recording recording = new Recording()) {
        recording.addEventCallback("jdk.VirtualThreadPinned", event -> {
            // 事件处理逻辑
            System.out.println("虚拟线程被固定");
        });
        recording.start();
        // 启动虚拟线程执行同步块逻辑
        Thread.ofVirtual().start(() -> {
            synchronized (lockObj) {
                try { Thread.sleep(50); } catch (InterruptedException e) {}
            }
        });
        Thread.sleep(100); // 等待事件触发
    }
    

4. JDK版本潜在bug

你使用的JDK21.0.3+7-LTS-152存在部分虚拟线程事件触发的已知问题,建议升级到JDK21的最新小版本(如21.0.4+7)再测试,确认是否是版本导致的事件不触发。

5. 虚拟线程执行上下文异常

如果虚拟线程被包装在ForkJoinPool或其他调度器中执行,可能会影响JVM对线程固定状态的判定,确保虚拟线程是直接通过Thread.ofVirtual().start()或ExecutorService.newVirtualThreadPerTaskExecutor()创建并执行同步逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 11:50:00