Java 21 新特性:虚拟线程
Java 21 是继 Java 17 之后的新一代长期支持版本LTS。在 Java 21 的众多新特性中最值得我们求职者关注的就是虚拟线程Virtual Thread。虚拟线程并不是一种让 CPU 计算变快的“超级线程”它主要解决的是在大量请求都需要等待数据库、网络接口等 I/O 操作时传统线程数量不够用、创建成本又太高的问题。本文先用人话解释虚拟线程为什么出现、它是怎么运行的然后再介绍具体用法和注意事项。最后一笔带过Java 21 的其他常用特性。一、先理解三种线程学习虚拟线程之前需要先分清操作系统线程、平台线程和虚拟线程。1.操作系统线程操作系统线程是由 Windows、Linux 等操作系统直接管理的线程。它的特点是“比较重”创建和销毁需要操作系统参与。每个线程都要占用一定内存。线程切换需要进入操作系统内核存在性能成本。单个进程能够创建的线程数量有限具体上限受内存、操作系统配置等因素影响。我们可以把操作系统线程理解成饭店里的真实服务员。招聘一个服务员需要成本饭店也不可能同时雇佣几十万个服务员。2.平台线程在以前的 Java 中通过new Thread()创建的线程通常是平台线程Thread thread new Thread(() - { System.out.println(执行任务); }); thread.start();平台线程由 JVM 提供给 Java 程序使用但底层通常对应一个操作系统线程Java 平台线程 ↓ 操作系统线程因此平台线程实际上是 JVM 对操作系统线程的一层包装。操作系统线程比较昂贵平台线程自然也不能无限创建。传统项目通常会创建线程池让少量平台线程反复处理任务ExecutorService pool Executors.newFixedThreadPool(200);相当于饭店只雇佣 200 个服务员让大量订单排队等待这 200 个服务员处理。3.虚拟线程虚拟线程是由 JVM 管理的轻量级线程在 JDK 19 中首次以预览特性出现并在 JDK 21 中正式发布。它和平台线程最大的区别是传统方式一个平台线程通常对应一个操作系统线程 虚拟线程大量虚拟线程复用少量平台线程可以把它们理解成虚拟线程一张订单平台线程真正处理订单的服务员JVM负责派发订单的经理操作系统线程服务员实际占用的工作岗位订单可以有几十万张但并不需要几十万个服务员。JVM 会安排少量平台线程轮流执行大量虚拟线程。二、为什么需要虚拟线程1.传统“一请求一线程”模型的问题传统 Web 服务器经常采用“一次请求对应一个线程”的处理模型请求 1 → 平台线程 1 请求 2 → 平台线程 2 请求 3 → 平台线程 3这种模型很好理解代码也容易编写。但平台线程数量有限当请求量很大时线程资源可能成为系统瓶颈。更麻烦的是大部分后端请求并不是一直在使用 CPU而是在等待接收请求 ↓ 查询数据库 ↓ 等待数据库返回 ← 大部分时间可能花在这里 ↓ 处理查询结果 ↓ 返回响应假设一次数据库查询需要等待两秒。使用传统平台线程时这个线程可能会被当前请求占用两秒但在等待期间它并没有真正执行多少计算。如果同时有大量请求都在等待数据库或远程接口就会出现大量平台线程处于阻塞等待状态。线程占用了内存却没有充分使用 CPU。请求继续增加后只能在线程池队列里排队。线程过多还会增加操作系统的调度和切换成本。2.虚拟线程如何解决虚拟线程执行到可识别的阻塞 I/O 操作时JVM 可以暂时把它从当前平台线程上卸载下来。虚拟线程 A发起数据库查询需要等待 ↓ JVM 保存虚拟线程 A 当前执行到哪里 ↓ 平台线程空出来开始执行虚拟线程 B ↓ 数据库结果返回后再继续执行虚拟线程 A用饭店来比喻服务员把菜单交给厨房后不需要站在厨房门口一直等。他可以先去处理其他订单等厨房做好以后再回来继续处理原来的订单。因此少量平台线程可以支撑大量正在等待 I/O 的虚拟线程。整体关系大致如下虚拟线程 1 ─┐ 虚拟线程 2 ─┤ 虚拟线程 3 ─┼──→ 少量平台线程 ──→ 少量操作系统线程 虚拟线程 4 ─┤ 虚拟线程 5 ─┘这里负责实际执行虚拟线程的平台线程也经常被称为载体线程Carrier Thread。三、虚拟线程是如何切换的线程要想暂停后继续运行系统必须知道它刚才执行到了哪里并保存相关数据例如方法调用到了哪一层方法中的局部变量下一条要执行的指令位置这些信息可以简单理解为线程的“工作现场”。当虚拟线程因为 I/O 等待而暂停时JVM 会保存它的工作现场让平台线程去执行其他虚拟线程等条件满足后JVM 再恢复这个虚拟线程。因此虚拟线程的切换主要由 JVM 在用户态完成不需要每次都让操作系统切换一个重量级线程成本通常更低。不过需要注意虚拟线程只是共享平台线程并不是所有虚拟线程都能在同一时刻并行运行。真正同时运行多少任务最终仍然受到 CPU 核心数和平台线程数量限制。虚拟线程的优势是让平台线程在其他任务等待 I/O 时不闲着。四、如何创建虚拟线程Java 21 提供了多种创建虚拟线程的方式。1.直接启动虚拟线程public class VirtualThreadDemo { public static void main(String[] args) throws InterruptedException { Thread thread Thread.startVirtualThread(() - { System.out.println(当前线程 Thread.currentThread()); }); thread.join(); } }Thread.startVirtualThread()会创建并立即启动一个虚拟线程。2.使用Thread.ofVirtual()public class VirtualThreadBuilderDemo { public static void main(String[] args) throws InterruptedException { Thread thread Thread.ofVirtual() .name(order-task) .start(() - System.out.println(处理订单)); thread.join(); } }这种方式可以为虚拟线程设置名称方便日志记录和问题排查。3.使用虚拟线程执行器在实际项目中更常见的方式是使用Executors.newVirtualThreadPerTaskExecutor()import java.util.concurrent.Executors; import java.util.stream.IntStream; public class VirtualThreadExecutorDemo { public static void main(String[] args) { try (var executor Executors.newVirtualThreadPerTaskExecutor()) { IntStream.range(0, 10_000).forEach(i - executor.submit(() - { Thread.sleep(1_000); System.out.println(任务 i 执行完成); return i; }) ); } } }这段代码会为每个任务创建一个虚拟线程。虽然提交了 10,000 个任务但并不意味着操作系统会创建 10,000 个线程。虚拟线程执行器实现了AutoCloseable离开try代码块时会等待已提交任务结束。五、平台线程和虚拟线程的区别对比项平台线程虚拟线程管理者操作系统为主JVM 为主与操作系统线程的关系通常近似一对一多个虚拟线程复用少量平台线程创建成本较高较低内存占用较大较小并可按需增长可创建数量相对有限可以创建非常多是否需要线程池复用通常需要通常不需要适合场景通用尤其是固定数量的计算任务大量并发、阻塞式 I/O 任务这里的“可以创建非常多”不等于完全没有成本。每个虚拟线程仍然需要保存自己的状态创建数量最终仍受可用内存等资源限制。六、虚拟线程适合哪些场景虚拟线程特别适合任务数量多而且任务经常等待 I/O 的场景。适合的场景Web 请求处理JDBC 数据库查询HTTP、RPC 远程调用文件读写消息消费大量需要等待结果的独立任务例如一个订单接口需要依次查询数据库、调用库存服务和支付服务大部分时间都在等待外部结果这种场景很适合虚拟线程。不会明显受益的场景视频编码图片压缩密码计算大规模数学运算其他长时间占用 CPU 的任务如果任务一直在计算没有阻塞等待虚拟线程就没有机会卸载并让出平台线程。例如一台机器只有 8 个 CPU 核心即使创建 10 万个虚拟线程执行纯计算也不可能让 10 万个任务真正同时计算。任务反而可能因为频繁调度而变慢。所以要记住虚拟线程解决的是“线程被大量等待占住”的问题不是“CPU 不够快”的问题。七、虚拟线程常见误区误区 1虚拟线程比普通线程执行得更快不准确。执行同一段纯计算代码时虚拟线程不一定更快。它的优势是等待 I/O 时可以释放载体线程从而提高系统吞吐量。误区 2有了虚拟线程就不需要数据库连接池不正确。数据库连接本身是昂贵且有限的资源仍然需要连接池管理。误区 3虚拟线程数量没有上限不正确。虚拟线程很轻但仍然会占用内存和 JVM 管理资源只是可创建数量通常远高于平台线程。误区 4虚拟线程等于异步编程不完全相同。虚拟线程允许开发者继续使用容易理解的同步阻塞代码User user userService.findById(id); ListOrder orders orderService.findByUserId(id); return new UserDetail(user, orders);代码看起来仍然是从上往下执行的但线程在等待 I/O 时JVM 可以在底层调度其他虚拟线程。它的价值之一就是在获得高并发能力的同时避免把业务代码写成大量回调或复杂的异步调用链。八、Java 21 的其他常用新特性除了虚拟线程Java 21 还有几个值得了解的正式特性。1.switch模式匹配可以直接根据对象类型进行分支判断static String format(Object value) { return switch (value) { case Integer i - 整数 i; case String s - 字符串 s; case null - 空值; default - 其他类型; }; }相比连续使用多个if instanceof代码更加清晰。2. 记录模式可以直接拆解record中的数据record Point(int x, int y) {} static void print(Object value) { if (value instanceof Point(int x, int y)) { System.out.println(x x , y y); } }3. 顺序集合Java 21 新增了SequencedCollection、SequencedSet和SequencedMap统一提供首元素、尾元素和反向视图等操作ListString list new ArrayList(List.of(A, B, C)); list.addFirst(Start); list.addLast(End); System.out.println(list.getFirst()); System.out.println(list.getLast()); System.out.println(list.reversed());4. 分代 ZGCJava 21 为 ZGC 引入分代回收能力。它根据“大多数新对象存活时间很短”的特点对年轻对象和长期存活对象分别管理从而降低部分场景下的垃圾回收成本。Java 21 中可以通过以下参数启用java -XX:UseZGC -XX:ZGenerational MyApplication是否切换垃圾收集器应以真实业务压测结果为准。九、总结虚拟线程的核心思想其实就是让大量轻量级虚拟线程复用少量重量级平台线程。当一个虚拟线程等待 I/O 时平台线程可以先去执行其他虚拟线程。最后总结一下平台线程通常接近一个 Java 线程对应一个操作系统线程创建成本较高。虚拟线程由 JVM 管理大量虚拟线程可以复用少量平台线程。虚拟线程适合大量数据库、网络、文件等阻塞 I/O 任务。虚拟线程不会让纯 CPU 计算变快也不会扩大数据库和下游服务的容量。对于传统的“一请求一线程”Java Web 应用虚拟线程降低了高并发编程的门槛。开发者可以继续使用直观的同步代码同时减少大量平台线程阻塞等待造成的资源浪费。这也是虚拟线程成为 Java 21 最重要新特性之一的原因。最后如果你觉得本篇内容对你有帮助的话欢迎点赞关注评论谢谢⭐⭐⭐

相关新闻

1600张表,手动整理?

1600张表,手动整理?

算笔账。1613张表,每张表平均26个字段,手动复制粘贴到Excel,一张表至少3分钟。1600张表就是80个小时——整整两周不干别的,光整理文档。 而且这只是第一次。以后每次数据库变更,都要手动对比哪里改了、更新文档、标注新…

2026/9/24 6:20:45 阅读更多 →
Unity Android项目性能优化全攻略

Unity Android项目性能优化全攻略

1. 为什么Unity Android项目需要专门优化?移动端与PC平台存在本质差异,Android设备更是性能表现参差不齐。我在2018年接手过一个跑在千元机上的AR项目,默认Quality Settings下帧率直接跌破10FPS。通过系统优化后,中端设备也能稳定…

2026/9/23 5:06:25 阅读更多 →
LuaDec51反编译实战:从字节码还原逻辑的完整指南

LuaDec51反编译实战:从字节码还原逻辑的完整指南

1. 项目概述:为什么我们需要Lua反编译?在游戏开发、嵌入式系统、甚至是一些服务端应用中,Lua脚本的身影无处不在。它轻量、高效、易于嵌入,是许多开发者实现热更新和逻辑分离的首选。然而,当你拿到一个只有编译后的.lu…

2026/9/24 4:11:34 阅读更多 →

最新新闻

LT6911C HDMI转MIPI DSI/CSI方案详解:从硬件设计到驱动调试

LT6911C HDMI转MIPI DSI/CSI方案详解:从硬件设计到驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 1:31:32 阅读更多 →
dsh-anchored-standard的Resident目录与按需解锁机制:dev_tool_search工具搜索模式完整教程

dsh-anchored-standard的Resident目录与按需解锁机制:dev_tool_search工具搜索模式完整教程

dsh-anchored-standard的Resident目录与按需解锁机制:dev_tool_search工具搜索模式完整教程 【免费下载链接】dsh-anchored-standard Two-phase DeepSeek Harness preset: Minimal-aligned bootstrap, then full Standard tools (Project2 98/99) 项目地址: https…

2026/9/25 1:31:32 阅读更多 →
UPX加壳脱壳管家:PE信息分析与一键强制叠加脱壳实战

UPX加壳脱壳管家:PE信息分析与一键强制叠加脱壳实战

简介:这是一套面向逆向工程初学者与安全测试人员的UPX加壳脱壳辅助工具,围绕一键加壳、一键脱壳与PE信息分析三大能力展开,帮助使用者快速完成可执行文件的压缩保护与还原验证。工具支持常规、最佳压缩、暴力、超暴力等多档压缩等级&#xff…

2026/9/25 1:31:32 阅读更多 →
基于Hadoop的电影网站用户性别预测:从日志预处理到模型部署

基于Hadoop的电影网站用户性别预测:从日志预处理到模型部署

简介:这是一份基于Hadoop的电影网站用户性别预测项目参考代码,源自课本实践案例,适合正在学习大数据处理、MapReduce编程或KNN分类算法的学生与开发者。资源包共60个文件,以28个class编译文件和26个java源码为主,另含p…

2026/9/25 1:31:32 阅读更多 →
可信网络安全平台实施指南:从安装手册模板到生产环境部署

可信网络安全平台实施指南:从安装手册模板到生产环境部署

简介:这份安元可信网络安全平台安装手册模板来源于北京明朝万达科技 Chinasec(安元)可信网络安全平台 V3.1,面向网络安全运维、系统集成与交付人员,适合在部署可信安全管控平台前理清整体架构、组件组成与安装流程。文…

2026/9/25 1:31:32 阅读更多 →
QQ截图钉在桌面怎么用?让截图悬浮置顶,学习办公效率翻倍

QQ截图钉在桌面怎么用?让截图悬浮置顶,学习办公效率翻倍

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 1:30:31 阅读更多 →

日新闻

AI元人文:从工具使用到思维重构的深度探索

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:00:41 阅读更多 →
Python+CNN车牌识别实战:从数据预处理到模型训练与部署

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:00:41 阅读更多 →
Vim基础操作全攻略:保存退出、模式切换与高频命令实战

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/25 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/24 9:10:42 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →