必须同时配置jdk 21、编译参数启用预览特性、运行时添加--enable-preview;idea需设sdk和字节码版本,gradle需在build.gradle中为test/run任务显式配置jvmargs,vs code需在launch.json中添加vmargs。

IDEA里开Java 21虚拟线程需要改哪些地方
必须同时满足三个条件:JDK版本、编译参数、运行参数,缺一不可。只装了JDK 21但没加预览开关,--enable-preview 一漏,Thread.ofVirtual() 直接抛 UnsupportedOperationException。
- 确认用的是 JDK 21(不是 JRE,也不是 OpenJDK 21 以外的构建,比如某些 Linux 包管理器装的“jdk-21”可能其实是旧版别名)
- 项目 SDK 设置指向真实 JDK 21 根目录(IntelliJ → Project Structure → Project → Project SDK)
- 在
Settings → Build → Compiler → Java Compiler中把Target bytecode version设为21,并勾选Enable preview features - 在
Run → Edit Configurations → Modify options → Add VM options里填入:--enable-preview(注意是双横线,不是单横线或中文符号)
Gradle项目跑虚拟线程报错“preview feature not enabled”
Gradle 默认不透传 JVM 预览参数给测试或运行任务,光在 IDEA 里配了 VM options 没用——那是 IDE 启动进程用的,不是 Gradle fork 出来的 JVM。
- 在
build.gradle里显式启用预览:java { toolchain { languageVersion = JavaLanguageVersion.of(21) } } test { jvmArgs = ['--enable-preview'] } run { jvmArgs = ['--enable-preview'] } - 如果用 Kotlin DSL(
build.gradle.kts),写法稍不同:jvmArgs("--enable-preview"),不是数组字面量 - 执行时别用
./gradlew run就完事,先 clean:IDEA 缓存可能卡住旧 class 文件,导致即使改了配置也继续报错
为什么 Thread.start() 能用,Thread.ofVirtual() 却报错
虚拟线程是预览特性,所有相关 API(如 Thread.ofVirtual()、StructuredTaskScope)都带运行时校验,只要 JVM 启动时没带 --enable-preview,调用就直接失败,不等你 new 对象或 start。
-
Thread.start()是传统线程,和预览无关;而Thread.ofVirtual()内部会检查VM.isPreviewEnabled(),不通过就 throw - 常见误操作:只在 main 方法里加了
--enable-preview,但单元测试用的是 Gradle test task,没单独配,结果测试里全挂 - 验证是否生效最简单方式:在代码里打印
System.getProperty("jdk.enablePreview"),输出true才算到位
VS Code + Extension Pack for Java 怎么配
VS Code 不像 IDEA 有图形化 VM options 入口,全靠配置文件驱动,容易漏掉其中一环。
立即学习“Java免费学习笔记(深入)”;
- 确保
java.home设置正确(VS Code 设置搜java.home,值应为 JDK 21 的绝对路径,比如/usr/lib/jvm/jdk-21) - 在项目根目录加
.vscode/settings.json:{ "java.configuration.updateBuildConfiguration": "interactive", "java.compile.nullAnalysis.mode": "automatic" } - 关键一步:在
.vscode/launch.json的配置项里加"vmArgs": ["--enable-preview"],且该配置必须用于type: "java"的 launch - 别依赖
java.debug.settings.vmArgs全局设置——它只影响调试,不影响 Ctrl+F11 运行










