资讯详情

虚拟线程-JDK21之后并发的换轨

📅 2026/10/30 2:42:38 | 华诺云谱 👁 阅读
虚拟线程-JDK21之后并发的换轨
虚拟线程JDK 21 之后并发的换轨一万个连接一万个线程的账以前的解法是 NIO 和多路复用让一个线程看一群连接。JDK 21 给了第二个答案把线程便宜到一万起步阻塞代码随便写。虚拟线程改变的是价格执行速度一寸没变。把这笔账算清就知道它替你省了什么、又埋了什么坑。平台线程贵在哪普通线程也叫平台线程一个线程一个 OS 调度单位栈内存一兆起步创建和上下文切换都要进内核。一万个平台线程光栈就吃掉几个 G切换开销把 CPU 吃满这就是 BIO 篇算过的账。贵的根源是「线程绑定 OS 资源」。虚拟线程便宜在哪虚拟线程是 JVM 自己调度的轻量任务。它跑在少量平台线程载体线程上遇到阻塞就从载体上下来把载体让给别人恢复时再找一个载体接着跑。栈按需增长一个虚拟线程的开销是千字节级创建十万个也只是内存里的一堆小对象。JEP 444 在 JDK 21 把它转正。少量载体线程十万个虚拟线程阻塞就换人任务1任务2……平台线程平台线程用法一行。Executors.newVirtualThreadPerTaskExecutor()每个任务一个虚拟线程或者Thread.ofVirtual().start(...)。这里有个反直觉的规矩虚拟线程不要池化它便宜到不需要复用池化反而把它的优势锁死。三个注意第一pinning 的旧账。虚拟线程在 synchronized 块里阻塞时曾经会把载体线程一起钉住外面的任务全等着这是虚拟线程早期最大的坑。JEP 491「Synchronize Virtual Threads without Pinning」把这个问题解掉了落地版本以 JEP 页为准核验 2026-10-25。老版本上跑高并发synchronized 是雷新版本上这颗雷已拆。第二ThreadLocal 的账。虚拟线程数量一大每个都持有一份 ThreadLocal 就是灾难连接池里的 ThreadLocal 尤其危险。上下文传递改用 ScopedValue预览特性或者显式传参是新姿势。第三CPU 密集型无收益。虚拟线程省的是「等」的时间计算密集的任务该多核还是多核换轨道不改变物理。亲手数一数下面用一段 Java 对照创建十万虚拟线程和五千平台线程的时间与内存。直接运行java VirtualBill.javaJDK 21推荐 24 以上。// 运行java VirtualBill.java// 对照虚拟线程与平台线程的创建账单。importjava.util.concurrent.CountDownLatch;importjava.util.concurrent.Executors;publicclassVirtualBill{staticlongusedHeapMB(){RuntimerRuntime.getRuntime();return(r.totalMemory()-r.freeMemory())/(1024*1024);}publicstaticvoidmain(String[]args)throwsException{intvirtualCount100_000;longbeforeusedHeapMB();longstartSystem.nanoTime();try(varexecutorExecutors.newVirtualThreadPerTaskExecutor()){CountDownLatchlatchnewCountDownLatch(virtualCount);for(inti0;ivirtualCount;i){executor.submit(()-{try{Thread.sleep(10);}catch(InterruptedExceptione){Thread.currentThread().interrupt();}latch.countDown();});}latch.await();}longms(System.nanoTime()-start)/1_000_000;System.out.printf(虚拟线程 %d 个%d ms堆 %d MB%n,virtualCount,ms,usedHeapMB()-before);intplatformCount5_000;beforeusedHeapMB();startSystem.nanoTime();Thread[]tsnewThread[platformCount];CountDownLatchlatchnewCountDownLatch(platformCount);for(inti0;iplatformCount;i){ts[i]newThread(()-{try{Thread.sleep(10);}catch(InterruptedExceptione){Thread.currentThread().interrupt();}latch.countDown();});ts[i].start();}latch.await();for(Threadt:ts){t.join();}ms(System.nanoTime()-start)/1_000_000;System.out.printf(平台线程 %d 个%d ms堆 %d MB%n,platformCount,ms,usedHeapMB()-before);System.out.println(数量差 20 倍账单差得更多这就是价格差。);}}适用边界这一篇管虚拟线程的机制与用法。结构化并发、作用域值的完整 API以及 Web 容器Tomcat 2024 起支持上的实测表现是另外的题。和线程池篇对起来读最有意思线程池的七个参数是在为「线程贵」做精算虚拟线程时代那套精算大半作废但池化思维里的拒绝、排队、隔离换个形态依然存在。跑完演示再看你的服务阻塞点满天飞的 I/O 密集服务是第一批换轨的候选改一行启动代码就能试。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑