在一个高并发服务里,给一个
synchronized块加了日志,发现虚拟线程不再被“钉”在某个内核线程上——那一刻我觉得,Loom 的承诺正在变成现实。
2025 年 3 月 18 日,JDK 24 正式发布。作为继 JDK 23 之后的又一个短期版本,它的生命周期依然只有半年。很多人会觉得这种只有半年生命周期的临时版本,没有太大的用处。但是我觉得:正是因为它们,后续的LTS版本才能伟大。它也代表了 Java 社区正在认真在为开发者考虑开发体验。
虽然这次更新没有 LTS 那样的宏大叙事,JDK 24 的改进却直击要害:一个存在了二十多年的安全组件终于正式退休,一个困扰虚拟线程用户的同步问题得到了优雅解决。这些改动,有的是告别,有的是新生。
所有特性均基于 JSR 399(《Java SE 24 发布规范》)。作为一个典型的短期版本,它主要聚焦:
SecurityManager,为平台减负。synchronized 同步导致的“钉住”(Pinning)问题,释放 Loom 全部潜力。这是一个时代的终结。自 Java 1.0 起就存在的 SecurityManager,在 JDK 24 中被永久禁用。
多年来,SecurityManager 旨在提供一个沙箱模型来限制代码权限。然而,它在实践中极少被正确使用,反而因其复杂的实现和对性能的影响,成为了 JVM 的一个沉重负担。从 JDK 17 开始,它就被标记为“遗留”,而 JDK 24 则彻底移除了它的功能。
SecurityManager(绝大多数应用都是如此),那么升级到 JDK 24 将毫无感知,但 JVM 内部会变得更简洁、更高效。对于构建工具、测试框架、字节码分析库的开发者来说,这是一个期盼已久的礼物。长久以来,操作 .class 文件只能依赖 ASM、Byte Buddy 等第三方库,这带来了版本兼容性和维护成本的问题。
JDK 24 正式发布了 标准的 Class-File API,提供了一套稳定、官方的方式来读取、分析、修改和生成 class 文件。
这不仅是 API 的增加,更是对 Java 工具链生态的一次重要赋能。
这是 Project Loom 在 JDK 24 带来的最令人兴奋的改进。在之前的版本中,如果一个虚拟线程执行了 synchronized 块或方法,它会被“钉住”(Pinned)——即绑定到一个特定的底层平台线程上,无法被调度器挂起和迁移。
这违背了虚拟线程轻量、可大规模并发的初衷。JEP 491 通过一种巧妙的机制解决了这个问题:
synchronized 块时,如果检测到可能阻塞,它会将监视器(monitor)的所有权委托给一个专用的平台线程,然后自己可以自由地被挂起和调度。synchronized,虚拟线程依然能保持其高并发、低内存占用的优势。这意味着,你可以几乎无痛地将现有基于线程池的阻塞式 I/O 应用迁移到虚拟线程模型上。// 一个典型的 Web 控制器方法
@GetMapping("/user/{id}")
public User getUser(@PathVariable String id) {
// 即使这里调用了 synchronized 方法
return userService.findById(id); // <-- 假设内部有 synchronized 逻辑
}在 JDK 24 之前,这个看似简单的请求可能会因为内部的 synchronized 而“钉住”一个宝贵的平台线程。而在 JDK 24 中,虚拟线程可以自由调度,极大地提升了系统的整体吞吐量。
Stream API 自 Java 8 引入以来,一直是函数式编程的利器。但在处理一些复杂场景(如滑动窗口、批处理、分组聚合)时,常常力不从心,不得不退回到命令式循环。
JEP 485 引入了 Gatherers,为 Stream 提供了一种强大且声明式的方式来定义自定义的中间操作。
// 示例:创建一个滑动窗口收集器
Gatherer<Integer, ?, List<List<Integer>>> windowGatherer =
Gatherers.windowFixed(3);
List<Integer> numbers = List.of(1, 2, 3, 4, 5);
List<List<Integer>> windows = numbers.stream()
.gather(windowGatherer)
.toList();
// 结果: [[1, 2, 3], [2, 3, 4], [3, 4, 5]]这不仅仅是语法糖,它极大地扩展了 Stream API 的表达能力,让复杂的流处理逻辑也能保持清晰和简洁。对于数据处理、实时分析等场景,这是一个巨大的生产力提升。
SecurityManager 的正式退休,标志着 Java 平台向更简洁、更现代的架构迈出了坚实一步。synchronized 钉住问题,是虚拟线程走向全面普及的关键一环,让高并发编程的门槛进一步降低。JDK 24 通过 JSR 399,完成了一次兼具“破”与“立”的迭代。它勇敢地告别了 SecurityManager 这个历史包袱,为平台瘦身;同时,它又通过解决虚拟线程的“钉住”问题和引入 Stream Gatherers,为未来的并发编程和数据处理铺平了道路。这些改动,无论是大刀阔斧的清理,还是精雕细琢的优化,都指向同一个目标:让 Java 平台更健壮、更高效、更好用。JDK 24 再次证明,Java 的演进是一场既敢于告别过去,又勇于拥抱未来的坚定旅程。
[1] JSR 399: Java SE 24 规范: https://www.jcp.org/en/jsr/detail?id=399
[2] OpenJDK JDK 24 官方页面: https://openjdk.org/projects/jdk/24/
[3] JEP 486: Permanently Disable the Security Manager: https://openjdk.org/jeps/486
[4] JEP 491: Synchronize Virtual Threads without Pinning: https://openjdk.org/jeps/491
[5] JEP 485: Stream Gatherers: https://openjdk.org/jeps/485