0

0

如何配置Java 21的新特性虚拟线程(Virtual Threads)_高并发轻量级方案

P粉602998670

P粉602998670

发布时间:2026-03-02 10:56:03

|

773人浏览过

|

来源于php中文网

原创

java 21虚拟线程需显式启用--enable-preview,thread.ofvirtual()适用于短时精确控制任务,executors.newvirtualthreadpertaskexecutor()适合批量i/o但须手动关闭;避免synchronized和阻塞jni以防钉住carrier线程;jstack默认不显示虚拟线程栈,应配合-djdk.tracepinnedthread=full和jfr调试。

如何配置java 21的新特性虚拟线程(virtual threads)_高并发轻量级方案

Java 21 启动时必须加 --enable-preview

虚拟线程是 Java 21 的预览特性,不是默认开启的。不加参数直接跑 Thread.ofVirtual().start() 会抛 UnsupportedOperationException,错误信息里通常带 “preview” 字样。

实操建议:

得到AI工具箱
得到AI工具箱

发现好用的AI工具

下载
  • 启动命令必须显式加上 --enable-preview,例如:java --enable-preview MyApp
  • 如果用 Maven,需在 maven-compiler-plugin 中配置 <forcejavaccompileruse>true</forcejavaccompileruse>,并设 <compilerargs></compilerargs> 包含 -XX:+EnablePreview
  • IDE(如 IntelliJ)需要在运行配置的 VM options 里手动填入 --enable-preview,光改语言级别没用

Thread.ofVirtual()Executors.newVirtualThreadPerTaskExecutor() 别混用

两者都创建虚拟线程,但生命周期管理和适用场景完全不同:前者适合短时、明确控制的单次任务;后者本质是无界线程池,适合大量异步 I/O 场景,但容易掩盖资源泄漏。

常见错误现象:用 Executors.newVirtualThreadPerTaskExecutor() 提交了数百个阻塞读取 HTTP 的任务,结果发现内存持续上涨,GC 压力大——因为虚拟线程虽轻量,但其栈帧、监控对象、关联的 Fiber 实例仍占堆内存,且该 executor 不自动关闭。

立即学习Java免费学习笔记(深入)”;

实操建议:

  • 短任务、需精确控制启停:用 Thread.ofVirtual().unstarted(runnable).start()
  • 批量 I/O 密集型任务(如爬虫、网关转发):用 Executors.newVirtualThreadPerTaskExecutor(),但务必配合 try-with-resources 或显式 close()
  • 别把它当传统线程池用——它不复用线程,也不限制并发数,失控时比 newFixedThreadPool(1000) 更危险

虚拟线程阻塞时不会压垮 OS 线程,但 synchronized 和 JNI 仍是瓶颈

虚拟线程的优势在于挂起/恢复由 JVM 管理,不绑定 OS 线程。但一旦进入 JVM 外部阻塞点(比如 synchronized 块、Object.wait()、或任何 JNI 调用),它就会“钉住”(pin)当前 carrier thread,导致该 OS 线程无法被其他虚拟线程复用。

性能影响明显:10 万个虚拟线程里若有 1% 钉住 carrier,就可能把默认 256 个 carrier 线程全占满,后续虚拟线程只能排队等待,吞吐骤降。

实操建议:

  • 避免在虚拟线程中使用 synchronized,改用 ReentrantLock(非公平模式)或无锁结构(如 ConcurrentHashMap
  • 数据库连接、文件读写等 I/O 操作,优先走 NIO(AsynchronousFileChannelCompletableFuture.supplyAsync(..., executor))而非阻塞 API
  • JNI 调用前确认是否可重入/非阻塞;否则考虑把该逻辑剥离到专用平台线程池执行

监控和调试时看不到虚拟线程的完整栈,jstack 默认不显示

jstack <pid></pid> 输出里,虚拟线程默认只显示为 "VirtualThread[#n]/runnable",没有 Java 栈帧,对排查死锁、慢调用几乎无效。这是最常被忽略的运维盲区。

实操建议:

  • 启动时追加 -Djdk.tracePinnedThread=full,当虚拟线程被钉住时会打印警告及栈信息
  • jcmd <pid> VM.native_memory summary</pid> 观察 carrier thread 数量是否异常增长
  • JDK 21+ 推荐用 jfr start --duration=60s --settings profile -o dump.jfr 录制飞行记录,然后用 JDK Mission Control 打开,能清晰看到每个虚拟线程的状态变迁和阻塞点

虚拟线程不是银弹——它简化的是线程创建和调度成本,而不是消除同步竞争或 I/O 等待。真正卡住系统的,往往还是那几行 synchronized 或一个没设超时的 HttpClient 请求。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Java Maven专题
Java Maven专题

本专题聚焦 Java 主流构建工具 Maven 的学习与应用,系统讲解项目结构、依赖管理、插件使用、生命周期与多模块项目配置。通过企业管理系统、Web 应用与微服务项目实战,帮助学员全面掌握 Maven 在 Java 项目构建与团队协作中的核心技能。

0

2025.09.15

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

430

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

599

2023.08.10

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

430

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

599

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

723

2023.08.10

Java 并发编程高级实践
Java 并发编程高级实践

本专题深入讲解 Java 在高并发开发中的核心技术,涵盖线程模型、Thread 与 Runnable、Lock 与 synchronized、原子类、并发容器、线程池(Executor 框架)、阻塞队列、并发工具类(CountDownLatch、Semaphore)、以及高并发系统设计中的关键策略。通过实战案例帮助学习者全面掌握构建高性能并发应用的工程能力。

95

2025.12.01

数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

379

2023.06.29

Golang 测试体系与代码质量保障:工程级可靠性建设
Golang 测试体系与代码质量保障:工程级可靠性建设

Go语言测试体系与代码质量保障聚焦于构建工程级可靠性系统。本专题深入解析Go的测试工具链(如go test)、单元测试、集成测试及端到端测试实践,结合代码覆盖率分析、静态代码扫描(如go vet)和动态分析工具,建立全链路质量监控机制。通过自动化测试框架、持续集成(CI)流水线配置及代码审查规范,实现测试用例管理、缺陷追踪与质量门禁控制,确保代码健壮性与可维护性,为高可靠性工程系统提供质量保障。

43

2026.02.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4万人学习

C# 教程
C# 教程

共94课时 | 10.5万人学习

Java 教程
Java 教程

共578课时 | 74.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号