JDK 21:并发与语言表达力,同时换代
JDK 21 是 8 / 11 / 17 之后最重要的 LTS 之一:虚拟线程让「一个请求一个线程」重新可行,switch 模式匹配与 record 模式让类型分支更安全,SequencedCollection 补齐了集合家族的首尾抽象。同时,它也是预览特性最密集的版本——正好用来学习 Java 的预览机制本身。
这一课,你必须能自己回答GOALS
合上资料后,逐条自述
- 虚拟线程解决了什么问题?它和平台线程、线程池分别是什么关系?为什么它不能加速 CPU 密集任务?
- JDK 21 的 switch 模式匹配解决了哪些旧写法的问题?「穷尽性」为什么必须配合 sealed / enum?
- SequencedCollection 补上了集合框架的哪块缺口?reversed() 是拷贝还是视图?
- 分代 ZGC 与 G1 的目标差异是什么?什么场景才应该考虑 ZGC?
- 结构化并发、Scoped Values 在 JDK 21 是什么状态?它们分别替代了什么旧模式?
- String Templates 为什么在 JDK 21 是预览、后来又被撤回?这说明预览机制意味着什么?
- FFM 在 21 是预览:Arena 和 MemorySegment 分别解决什么问题?downcall 与 upcall 的使用边界是什么?
- 从 8 / 11 / 17 升到 21,哪些 JVM 参数会让 JVM 直接拒绝启动?强封装问题应该怎么定位?
三种模式,各解决一个问题MODES
学习路径TRACKS
语法升级 · 1 天
从旧写法迁移如果你还在写 Java 8 风格,按「record → sealed → 模式匹配 → switch 表达式」顺序迁移,最后用 SequencedCollection 改造集合代码。
并发深钻 · 2 天
机制 + 排障从线程模型讲到 pinning、ThreadLocal 泄漏与结构化并发。重点不是 API,而是「什么任务适合虚拟线程」。
平台能力与迁移 · 1 天
预览能力 + 升级风险把 Scoped Values、FFM 这两项 JDK 21 预览能力与迁移清单放在一起看:一边理解下一代并发与本地互操作,一边排查升级到 21 的真实成本。
换一个版本,继续同一门课SWITCH
所有完整课程共用「速查 → 深钻 → 面试」结构。切换版本后,再从顶栏版本菜单切一次,就会落在目标版本的同一模块。
全部学习单元20
速查模块 · 12 个主题
语言与类型系统
JDK 21 的语言主线是「让数据形状与类型分支都变成一等公民」:record 定义数据,sealed 封闭类型集合,模式匹配负责安全解构,三者组合后可以写出接近代数数据类型的 Java。
集合与 SequencedCollection
JDK 21 给集合框架补上了迟到三十年的首尾抽象:SequencedCollection / SequencedSet / SequencedMap 统一了 getFirst、addLast、reversed 等操作,让 List、Deque、LinkedHashSet、SortedSet 第一次共享同一套顺序 API。
String 与文本处理
String 是不可变对象,所有「修改」都会产生新对象。JDK 15 的文本块、JDK 11 的 strip / repeat / lines、JDK 21 的 splitWithDelimiters 与带范围 indexOf,让多行文本和子串搜索少写很多样板代码。
JDK 21 新增 API
JDK 21 除了虚拟线程和模式匹配这两条主线,还补了一批小而实用的 API:Math.clamp、String 的区间 indexOf、splitWithDelimiters、StringBuilder.repeat、Character 的 emoji 判断、KEM 密钥封装,以及让 HttpClient 支持 try-with-resources。
Stream 与函数式处理
Stream 是「声明式流水线」:源 + 中间操作 + 终端操作。中间操作惰性执行,只有终端操作才会真正遍历。真正拉开水平差距的不是 map/filter,而是 Collectors 的组合与副作用边界。
java.time 日期与时间
java.time 用「机器时间 Instant + 人类时间 Local/Zoned + 时间量 Duration/Period」三组类型取代了 Date 与 Calendar。它不可变、线程安全,但 DST、格式化和时区转换仍然是最容易写错的地方。
并发基础与 CompletableFuture
JDK 21 的并发工具箱分成三层:线程与执行器负责「在哪跑」,同步原语负责「怎么安全共享」,CompletableFuture 负责「怎么组合异步结果」。虚拟线程改变了第一层的成本,但没有改变后两层的规则。
虚拟线程速查
虚拟线程把「线程」从操作系统资源变成 JVM 管理的轻量任务:阻塞时自动卸载,让一个请求一个线程的写法重新可行。它提升的是阻塞场景下的吞吐上限,不是单任务速度。
IO、NIO 与 HttpClient
日常 IO 的 90% 用 Files 就能完成:readString / writeString / newBufferedReader / lines / walk。需要高并发网络请求时用 HttpClient;只有大文件、零拷贝或内存映射才需要下沉到 Channel 与 ByteBuffer。
反射、注解与模块
反射让程序在运行时检查与调用类型,是框架的基石;代价是编译期安全、性能与模块封装。JDK 21 的反射要同时理解三件事:Class/Method API、MethodHandles 的低层访问、以及模块强封装对 setAccessible 的限制。
JVM、GC 与诊断工具
JDK 21 的运行时主线是「更低停顿 + 更强诊断」:G1 仍是默认 GC,分代 ZGC 转正;JFR 与 jcmd 覆盖了从 GC、线程到虚拟线程的主要排障路径。先学会拿数据,再谈调优。
从 8 / 11 / 17 迁移到 21
升级 JDK 21 的难点通常不在新语法,而在旧假设:被移除的 JVM 参数、Java EE 模块、强封装下的反射,以及预览特性对版本和启动参数的严格要求。先处理这些,再谈用虚拟线程。
深钻模块 · 8 个主题
虚拟线程:把阻塞变成廉价
虚拟线程把「线程」从操作系统资源变成 JVM 管理的轻量任务:阻塞时自动卸载,让一个请求一个线程的写法重新可行。它提升的是阻塞场景下的吞吐上限,不是单任务速度。
模式匹配:让数据形状成为控制流
模式匹配把「判断类型 → 强转 → 取字段」三步合并为一次声明:if (o instanceof Point(int x, int y))。在 switch 中配合 sealed 接口,还能让编译器检查分支是否穷尽。
SequencedCollection:集合终于有了「两端」
JDK 21 为 List、Deque、LinkedHashSet、SortedSet、LinkedHashMap、SortedMap 补上了统一的「首尾」API:addFirst、addLast、getFirst、getLast、reversed。以前每个实现各写一套,现在一套接口覆盖。
分代 ZGC:把停顿压到亚毫秒
JDK 21 的 ZGC 增加了分代模式:年轻代频繁回收、老年代偶尔回收,在保持亚毫秒级停顿的同时显著改善吞吐。它是大堆、低延迟服务的选项,不是所有场景的默认答案。
结构化并发:让任务有作用域
结构化并发把一组并发子任务放进一个作用域:父任务等待所有子任务结束,任一失败就取消其余,不再留下孤儿线程。JDK 21 中它是预览 API,配合虚拟线程和 ScopedValue 构成新的并发编程模型。
Scoped Values:有作用域的不可变上下文
ScopedValue 用「在某个作用域内绑定一个不可变值」替代 ThreadLocal 的可变副本:作用域结束自动失效,不需要 remove,也不会因为虚拟线程数量巨大而产生大量副本。JDK 21 是预览,JDK 25 转正。
预览特性:试用草案,而不是半成品
预览特性是已经进入 JDK、但尚未永久的语言或 API 改动:必须显式开启,可能在下一个版本调整或移除。JDK 21 同时存在 final、preview、incubator、experimental 四种状态,分清它们是升级不踩坑的前提。
FFM:用 Arena 和 MemorySegment 取代 JNI
Foreign Function & Memory API 让 Java 直接调用本地函数、管理堆外内存,并用 Arena 把「谁负责释放」变成可验证的生命周期约束。JDK 21 是第三轮预览,JDK 22 转正。
版本上下文JDK 21
JDK 21 于 2023-09-19 发布,是 8 / 11 / 17 之后的又一个 LTS。它把两条线同时推到终点:并发(虚拟线程转正)与语言表达力(switch 模式匹配、record 模式转正)。同时,它也是预览特性最密集的版本之一。