编程与软件开发

Project Loom 如何在 IntelliJ IDEA 中重塑 Java 并发编程

JetBrains 解释了 Project Loom 的各项功能如何结合虚拟线程、作用域值和结构化并发,以降低并发成本及其管理复杂度。文章指出,Structured Concurrency 在 Java 27 中仍是实验性功能,而 Virtual Threads 自 Java 21 起已稳定,Scoped Values 则自 Java 25 起已稳定。

2026-08-28
2 分钟阅读
8 浏览量
فريق تحرير certi.news
Project Loom 如何在 IntelliJ IDEA 中重塑 Java 并发编程

JetBrains 在一篇发表于 2026 年 8 月 27 日的博客文章中,对 Project Loom 在 IntelliJ IDEA 中的三个组件进行了实践解读:Virtual ThreadsScoped ValuesStructured Concurrency。其核心理念并不是增加彼此独立的 API,而是解决 Java 并发应用中的三个相互关联的问题:可扩展性、在任务之间传递上下文,以及管理线程和错误的生命周期。

文章指出,多线程代码仍然容易出现线程泄漏、异常被吞掉、竞态条件以及取消延迟等问题。此外,传统上依赖线程池和 CompletableFuture,可能会使取消逻辑和错误处理分散在多个分支中,从而增加在添加新的并发任务时未同步更新相关逻辑的可能性。

虚拟线程降低等待成本

虚拟线程基于 JEP 444,自 Java 21 起已稳定。与绑定到操作系统线程的平台线程不同,虚拟线程由 JVM 管理,创建成本低得多。JetBrains 指出,创建一个虚拟线程需要微秒级时间,而不是毫秒级时间;当虚拟线程等待数据库、网络连接、文件或同步机制时,它会释放平台线程。

这使虚拟线程尤其适合依赖阻塞操作的工作负载,因为预先调整线程池大小的需求会降低。文章还提到,Java 24 通过 JEP 491 引入了一项改进,使在 synchronized 方法或语句中被阻塞的虚拟线程能够释放平台线程,而不是继续占用它。

无需 ThreadLocal 问题的共享上下文

根据 JEP 506,Scoped Values 自 Java 25 起已稳定,解决的是另一个问题。应用通常需要将会话 ID 或跟踪 ID 等数据传递给请求的多个部分。过去通常通过 ThreadLocal 实现,但其值可以被修改,并且除非手动移除,否则会一直与线程生命周期绑定,这可能导致内存泄漏或安全问题。JetBrains 指出,即使开发者没有直接使用 ThreadLocal,Spring 等框架也可能在内部使用它。

ScopedValue 提供了一种模型:在特定作用域内只绑定一次值,然后自动将其提供给在该作用域中运行的代码,并在作用域结束时进行清理。作用域内部无法修改该绑定;与结构化并发结合使用时,该值还会传递给子任务,而无需显式传递上下文。实际上,这减少了开发者在执行并行任务时需要跟踪的控制点数量。

结构化并发将任务与明确的生命周期关联起来

Structured Concurrency 基于 JEP 533,旨在解决并发代码中的结构性问题。不过,它在 Java 27 中仍处于第七次预览阶段,因此 JetBrains 目前不建议在生产环境中使用。该概念将一组相关任务视为一个具有明确所有者、生命周期和失败策略的单一工作单元。

在 JetBrains 展示的示例中,应用并行获取客户订单记录和产品推荐,以构建客户档案。使用 StructuredTaskScope 可以设置两秒的超时时间,要求两个任务都成功,并在其中一个任务失败或超时时自动取消另一个任务。这样一来,无需在异常处理分支中重复调用 cancel(),取消策略成为任务作用域的一部分。

文章还解释了另一种不要求所有任务都成功的情况:如果应用从两个缓存中获取推荐,只需第一个成功响应,就可以使用 anySuccessfulOrThrow()。收到成功结果后,作用域会关闭,另一个任务也会自动取消;如果两个任务都失败,则会抛出一个说明失败原因的异常。

IntelliJ IDEA 内部发生了什么变化?

其价值不仅限于代码语法。从 IntelliJ IDEA 2026.1 起,在 StructuredTaskScope 内创建的虚拟线程会被收集到代表其作用域的容器中,使父任务与子任务之间的关系结构能够显示在调试器中。因此,线程转储不再只是显示通用线程池中的扁平线程列表,而是能更好地表明哪些任务属于同一个请求。

要尝试这些功能,开发者需要 Java 27;根据文章,该版本属于 Early Access 版本,并且需要设置语言级别才能使用实验性功能。IntelliJ IDEA 可以从项目设置中下载 JDK;使用 SDKMAN! 或 asdf 管理 JDK 版本时,它还会显示内嵌提示。此外,还可以使用 sts 直接模板创建 StructuredTaskScope 的初始结构。

certi.news 的编辑解读

这里真正发生的变化,是并发管理的一部分从开发者的手动责任转移到了这样一种模型:代码结构表达了任务的生命周期及其失败策略。Virtual Threads 解决可扩展性的成本问题,Scoped Values 规范上下文传递,而 Structured Concurrency 则试图让取消和错误传播变得可预测。这些功能结合起来,可能会减少那些需要并行执行多个等待操作的应用中的重复代码。

不过,演进的边界也很明确:Structured Concurrency 尚未稳定,而且文章发布时 Java 27 仍是 Early Access 版本。因此,博客文章并不能证明每个应用都会自动获得改进,也不会消除测试所使用的库和框架在这些模型下行为的必要性。当前对开发者而言,其价值在于理解并安全地试用这一模式,同时在实验性功能的接口稳定并积累足够的运行经验之前,将其留在生产环境之外。

新闻来源
JetBrains Blog
查看原始来源 ↗
ف
作者

فريق تحرير certi.news

同一分类

你可能还喜欢

查看所有新闻