首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >虚拟线程的pinned问题终于被jdk25完美解决了

虚拟线程的pinned问题终于被jdk25完美解决了

作者头像
菩提树下的杨过
发布2025-10-17 08:14:11
发布2025-10-17 08:14:11
12700
代码可运行
举报
运行总次数:0
代码可运行

虚拟线程是一个非常有用的特征,但是JDK25以前,一直存在pinned问题,一些场景下会导致平台线程被占用无法释放。

比如下面的代码,在JDK 21下运行时,会卡住:

代码语言:javascript
代码运行次数:0
运行
复制
import java.time.Duration;
import java.util.concurrent.Executors;

public class VirtualThreadPinningDemo {
    // 一个共享资源,我们将使用 synchronized 来保护它
    private static final Object sharedLock = new Object();

    public static void main(String[] args) {
        // 使用虚拟线程执行器创建大量虚拟线程
        try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
            for (int i = 0; i < 100; i++) {
                int taskId = i;
                executor.submit(() -> performTask(taskId));
            }
        }
        System.out.println("All tasks completed.");
    }

    private static void performTask(int id) {
        System.out.printf("Task %d started on thread: %s%n", id, Thread.currentThread());

        // 情况1:在 synchronized 块内进行阻塞操作 -> 会导致 PINNED
        synchronized (sharedLock) {
            System.out.printf("Task %d acquired lock. Thread: %s%n", id, Thread.currentThread());
            try {
                // 模拟一个阻塞操作,比如睡眠或I/O
                // 在 synchronized 块内睡眠,虚拟线程无法被卸载,平台线程被占用!
                Thread.sleep(Duration.ofSeconds(2));
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            System.out.printf("Task %d released lock.%n", id);
        }
        System.out.printf("Task %d finished.%n", id);
    }
}

  运行结果:

代码语言:javascript
代码运行次数:0
运行
复制
Task 0 started on thread: VirtualThread[#30]/runnable@ForkJoinPool-1-worker-1
Task 0 acquired lock. Thread: VirtualThread[#30]/runnable@ForkJoinPool-1-worker-1
Task 1 started on thread: VirtualThread[#32]/runnable@ForkJoinPool-1-worker-10
Task 4 started on thread: VirtualThread[#35]/runnable@ForkJoinPool-1-worker-9
Task 5 started on thread: VirtualThread[#36]/runnable@ForkJoinPool-1-worker-5
Task 6 started on thread: VirtualThread[#37]/runnable@ForkJoinPool-1-worker-6
Task 7 started on thread: VirtualThread[#38]/runnable@ForkJoinPool-1-worker-8
Task 2 started on thread: VirtualThread[#33]/runnable@ForkJoinPool-1-worker-3
Task 8 started on thread: VirtualThread[#39]/runnable@ForkJoinPool-1-worker-7
Task 9 started on thread: VirtualThread[#40]/runnable@ForkJoinPool-1-worker-2
Task 10 started on thread: VirtualThread[#41]/runnable@ForkJoinPool-1-worker-4
Task 11 started on thread: VirtualThread[#42]/runnable@ForkJoinPool-1-worker-11
Task 12 started on thread: VirtualThread[#43]/runnable@ForkJoinPool-1-worker-13
Task 14 started on thread: VirtualThread[#45]/runnable@ForkJoinPool-1-worker-14
Task 13 started on thread: VirtualThread[#44]/runnable@ForkJoinPool-1-worker-12
Task 15 started on thread: VirtualThread[#46]/runnable@ForkJoinPool-1-worker-15
Task 16 started on thread: VirtualThread[#47]/runnable@ForkJoinPool-1-worker-16
Task 0 released lock.
Task 0 finished.
Task 17 started on thread: VirtualThread[#48]/runnable@ForkJoinPool-1-worker-1
这里就卡住不向下走了

但是同样的代码,在JDK 25下,运行正常:

代码语言:javascript
代码运行次数:0
运行
复制
Task 2 started on thread: VirtualThread[#42]/runnable@ForkJoinPool-1-worker-3
Task 2 acquired lock. Thread: VirtualThread[#42]/runnable@ForkJoinPool-1-worker-3
Task 0 started on thread: VirtualThread[#37]/runnable@ForkJoinPool-1-worker-6
Task 3 started on thread: VirtualThread[#45]/runnable@ForkJoinPool-1-worker-6
Task 1 started on thread: VirtualThread[#39]/runnable@ForkJoinPool-1-worker-6
Task 4 started on thread: VirtualThread[#47]/runnable@ForkJoinPool-1-worker-6
Task 5 started on thread: VirtualThread[#48]/runnable@ForkJoinPool-1-worker-6
Task 7 started on thread: VirtualThread[#50]/runnable@ForkJoinPool-1-worker-6
Task 8 started on thread: VirtualThread[#53]/runnable@ForkJoinPool-1-worker-6
Task 9 started on thread: VirtualThread[#54]/runnable@ForkJoinPool-1-worker-6
Task 10 started on thread: VirtualThread[#55]/runnable@ForkJoinPool-1-worker-6
Task 11 started on thread: VirtualThread[#56]/runnable@ForkJoinPool-1-worker-6
Task 12 started on thread: VirtualThread[#57]/runnable@ForkJoinPool-1-worker-6
Task 13 started on thread: VirtualThread[#58]/runnable@ForkJoinPool-1-worker-6
Task 15 started on thread: VirtualThread[#60]/runnable@ForkJoinPool-1-worker-6
Task 16 started on thread: VirtualThread[#61]/runnable@ForkJoinPool-1-worker-6
Task 14 started on thread: VirtualThread[#59]/runnable@ForkJoinPool-1-worker-6
Task 17 started on thread: VirtualThread[#62]/runnable@ForkJoinPool-1-worker-6
Task 19 started on thread: VirtualThread[#64]/runnable@ForkJoinPool-1-worker-6
Task 18 started on thread: VirtualThread[#63]/runnable@ForkJoinPool-1-worker-6
Task 6 started on thread: VirtualThread[#49]/runnable@ForkJoinPool-1-worker-6
Task 21 started on thread: VirtualThread[#67]/runnable@ForkJoinPool-1-worker-6
Task 20 started on thread: VirtualThread[#66]/runnable@ForkJoinPool-1-worker-6
Task 22 started on thread: VirtualThread[#68]/runnable@ForkJoinPool-1-worker-6
Task 23 started on thread: VirtualThread[#69]/runnable@ForkJoinPool-1-worker-6
Task 24 started on thread: VirtualThread[#70]/runnable@ForkJoinPool-1-worker-6
Task 26 started on thread: VirtualThread[#72]/runnable@ForkJoinPool-1-worker-6
Task 25 started on thread: VirtualThread[#71]/runnable@ForkJoinPool-1-worker-6
Task 27 started on thread: VirtualThread[#73]/runnable@ForkJoinPool-1-worker-6
Task 28 started on thread: VirtualThread[#74]/runnable@ForkJoinPool-1-worker-3
Task 31 started on thread: VirtualThread[#77]/runnable@ForkJoinPool-1-worker-7
Task 30 started on thread: VirtualThread[#76]/runnable@ForkJoinPool-1-worker-7
Task 32 started on thread: VirtualThread[#78]/runnable@ForkJoinPool-1-worker-7
Task 29 started on thread: VirtualThread[#75]/runnable@ForkJoinPool-1-worker-7
Task 33 started on thread: VirtualThread[#79]/runnable@ForkJoinPool-1-worker-7
Task 34 started on thread: VirtualThread[#80]/runnable@ForkJoinPool-1-worker-7
Task 35 started on thread: VirtualThread[#81]/runnable@ForkJoinPool-1-worker-7
Task 36 started on thread: VirtualThread[#82]/runnable@ForkJoinPool-1-worker-7
Task 37 started on thread: VirtualThread[#83]/runnable@ForkJoinPool-1-worker-7
Task 38 started on thread: VirtualThread[#84]/runnable@ForkJoinPool-1-worker-7
Task 39 started on thread: VirtualThread[#85]/runnable@ForkJoinPool-1-worker-7
Task 41 started on thread: VirtualThread[#87]/runnable@ForkJoinPool-1-worker-7
Task 42 started on thread: VirtualThread[#88]/runnable@ForkJoinPool-1-worker-7
Task 40 started on thread: VirtualThread[#86]/runnable@ForkJoinPool-1-worker-7
Task 43 started on thread: VirtualThread[#89]/runnable@ForkJoinPool-1-worker-7
Task 44 started on thread: VirtualThread[#90]/runnable@ForkJoinPool-1-worker-7
Task 45 started on thread: VirtualThread[#91]/runnable@ForkJoinPool-1-worker-7
Task 46 started on thread: VirtualThread[#92]/runnable@ForkJoinPool-1-worker-7
Task 47 started on thread: VirtualThread[#93]/runnable@ForkJoinPool-1-worker-7
Task 48 started on thread: VirtualThread[#94]/runnable@ForkJoinPool-1-worker-7
Task 49 started on thread: VirtualThread[#95]/runnable@ForkJoinPool-1-worker-7
Task 50 started on thread: VirtualThread[#96]/runnable@ForkJoinPool-1-worker-7
Task 51 started on thread: VirtualThread[#97]/runnable@ForkJoinPool-1-worker-7
Task 52 started on thread: VirtualThread[#98]/runnable@ForkJoinPool-1-worker-7
Task 53 started on thread: VirtualThread[#99]/runnable@ForkJoinPool-1-worker-7
Task 54 started on thread: VirtualThread[#100]/runnable@ForkJoinPool-1-worker-7
Task 55 started on thread: VirtualThread[#101]/runnable@ForkJoinPool-1-worker-7
Task 56 started on thread: VirtualThread[#102]/runnable@ForkJoinPool-1-worker-7
Task 58 started on thread: VirtualThread[#104]/runnable@ForkJoinPool-1-worker-7
Task 59 started on thread: VirtualThread[#105]/runnable@ForkJoinPool-1-worker-7
Task 57 started on thread: VirtualThread[#103]/runnable@ForkJoinPool-1-worker-7
Task 60 started on thread: VirtualThread[#106]/runnable@ForkJoinPool-1-worker-7
Task 62 started on thread: VirtualThread[#108]/runnable@ForkJoinPool-1-worker-7
Task 63 started on thread: VirtualThread[#109]/runnable@ForkJoinPool-1-worker-7
Task 61 started on thread: VirtualThread[#107]/runnable@ForkJoinPool-1-worker-7
Task 64 started on thread: VirtualThread[#110]/runnable@ForkJoinPool-1-worker-7
Task 66 started on thread: VirtualThread[#112]/runnable@ForkJoinPool-1-worker-7
Task 65 started on thread: VirtualThread[#111]/runnable@ForkJoinPool-1-worker-7
Task 67 started on thread: VirtualThread[#113]/runnable@ForkJoinPool-1-worker-7
Task 68 started on thread: VirtualThread[#114]/runnable@ForkJoinPool-1-worker-7
Task 69 started on thread: VirtualThread[#115]/runnable@ForkJoinPool-1-worker-7
Task 70 started on thread: VirtualThread[#116]/runnable@ForkJoinPool-1-worker-7
Task 71 started on thread: VirtualThread[#117]/runnable@ForkJoinPool-1-worker-7
Task 72 started on thread: VirtualThread[#118]/runnable@ForkJoinPool-1-worker-7
Task 73 started on thread: VirtualThread[#119]/runnable@ForkJoinPool-1-worker-7
Task 74 started on thread: VirtualThread[#120]/runnable@ForkJoinPool-1-worker-7
Task 75 started on thread: VirtualThread[#121]/runnable@ForkJoinPool-1-worker-7
Task 76 started on thread: VirtualThread[#122]/runnable@ForkJoinPool-1-worker-7
Task 77 started on thread: VirtualThread[#123]/runnable@ForkJoinPool-1-worker-7
Task 78 started on thread: VirtualThread[#124]/runnable@ForkJoinPool-1-worker-7
Task 79 started on thread: VirtualThread[#125]/runnable@ForkJoinPool-1-worker-7
Task 80 started on thread: VirtualThread[#126]/runnable@ForkJoinPool-1-worker-7
Task 81 started on thread: VirtualThread[#127]/runnable@ForkJoinPool-1-worker-7
Task 82 started on thread: VirtualThread[#128]/runnable@ForkJoinPool-1-worker-7
Task 83 started on thread: VirtualThread[#129]/runnable@ForkJoinPool-1-worker-7
Task 84 started on thread: VirtualThread[#130]/runnable@ForkJoinPool-1-worker-7
Task 85 started on thread: VirtualThread[#131]/runnable@ForkJoinPool-1-worker-7
Task 86 started on thread: VirtualThread[#132]/runnable@ForkJoinPool-1-worker-7
Task 88 started on thread: VirtualThread[#134]/runnable@ForkJoinPool-1-worker-7
Task 87 started on thread: VirtualThread[#133]/runnable@ForkJoinPool-1-worker-7
Task 89 started on thread: VirtualThread[#135]/runnable@ForkJoinPool-1-worker-7
Task 90 started on thread: VirtualThread[#136]/runnable@ForkJoinPool-1-worker-7
Task 91 started on thread: VirtualThread[#137]/runnable@ForkJoinPool-1-worker-7
Task 92 started on thread: VirtualThread[#138]/runnable@ForkJoinPool-1-worker-7
Task 93 started on thread: VirtualThread[#139]/runnable@ForkJoinPool-1-worker-7
Task 94 started on thread: VirtualThread[#140]/runnable@ForkJoinPool-1-worker-7
Task 95 started on thread: VirtualThread[#141]/runnable@ForkJoinPool-1-worker-8
Task 97 started on thread: VirtualThread[#143]/runnable@ForkJoinPool-1-worker-8
Task 96 started on thread: VirtualThread[#142]/runnable@ForkJoinPool-1-worker-8
Task 98 started on thread: VirtualThread[#144]/runnable@ForkJoinPool-1-worker-3
Task 99 started on thread: VirtualThread[#145]/runnable@ForkJoinPool-1-worker-3
Task 2 released lock.
Task 2 finished.
Task 0 acquired lock. Thread: VirtualThread[#37]/runnable@ForkJoinPool-1-worker-7
Task 0 released lock.
Task 0 finished.
Task 3 acquired lock. Thread: VirtualThread[#45]/runnable@ForkJoinPool-1-worker-5
Task 3 released lock.
Task 3 finished.
Task 1 acquired lock. Thread: VirtualThread[#39]/runnable@ForkJoinPool-1-worker-7
Task 1 released lock.
Task 1 finished.
Task 4 acquired lock. Thread: VirtualThread[#47]/runnable@ForkJoinPool-1-worker-5
Task 4 released lock.
Task 4 finished.
Task 5 acquired lock. Thread: VirtualThread[#48]/runnable@ForkJoinPool-1-worker-7
Task 5 released lock.
Task 5 finished.
Task 7 acquired lock. Thread: VirtualThread[#50]/runnable@ForkJoinPool-1-worker-8
Task 7 released lock.
Task 7 finished.
Task 8 acquired lock. Thread: VirtualThread[#53]/runnable@ForkJoinPool-1-worker-8
Task 8 released lock.
Task 8 finished.
Task 9 acquired lock. Thread: VirtualThread[#54]/runnable@ForkJoinPool-1-worker-6
Task 9 released lock.
Task 9 finished.
Task 10 acquired lock. Thread: VirtualThread[#55]/runnable@ForkJoinPool-1-worker-8
Task 10 released lock.
Task 10 finished.
Task 11 acquired lock. Thread: VirtualThread[#56]/runnable@ForkJoinPool-1-worker-2
Task 11 released lock.
Task 11 finished.
Task 12 acquired lock. Thread: VirtualThread[#57]/runnable@ForkJoinPool-1-worker-8
Task 12 released lock.
Task 12 finished.
Task 13 acquired lock. Thread: VirtualThread[#58]/runnable@ForkJoinPool-1-worker-7
Task 13 released lock.
Task 13 finished.
Task 15 acquired lock. Thread: VirtualThread[#60]/runnable@ForkJoinPool-1-worker-7
Task 15 released lock.
Task 15 finished.
Task 16 acquired lock. Thread: VirtualThread[#61]/runnable@ForkJoinPool-1-worker-5
Task 16 released lock.
Task 16 finished.
Task 14 acquired lock. Thread: VirtualThread[#59]/runnable@ForkJoinPool-1-worker-2
Task 14 released lock.
Task 14 finished.
Task 17 acquired lock. Thread: VirtualThread[#62]/runnable@ForkJoinPool-1-worker-8
Task 17 released lock.
Task 17 finished.
Task 19 acquired lock. Thread: VirtualThread[#64]/runnable@ForkJoinPool-1-worker-8
Task 19 released lock.
Task 19 finished.
Task 18 acquired lock. Thread: VirtualThread[#63]/runnable@ForkJoinPool-1-worker-2
Task 18 released lock.
Task 18 finished.
... 会一直正常执行,直到运行结束

附:不熟悉虚拟线程pinned问题的,可参考deepseek的解释

image
image
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-10-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档