JEP 533(结构化并发第七个预览版)已经升级为 JDK 27 的正式功能。以 JDK 19 首次孵化以及 JDK 21 开始的多轮预览为基础,本轮迭代继续对该 API 进行优化。本轮更新的重点主要集中在如何将异常从作用域中传播出来。
结构化并发通过 java.util.concurrent.StructuredTaskScope 类提供,结合 Joiner 抽象,可以将一组相关的子任务视为单个工作单元。它解决了临时线程管理无法解决的三个问题:将子任务的生命周期限制在父作用域内、可靠地传播取消操作,以及在可观测性工具中呈现线程层次结构。预览版 6(JDK 26)新增了 onTimeout() 回调,并将 allSuccessfulOrThrow() 调整为返回 List
最显著的变化是三个标准连接器(joiner)的 join() 方法所抛出的新异常类型。在最近的预览版中,当子任务失败时,Joiner.allSuccessfulOrThrow()、anySuccessfulOrThrow() 和 awaitAllSuccessfulOrThrow() 会抛出预览版特有的 FailedException 异常。现在,在预览版 7 中,这些连接器会抛出 ExecutionException,这与 Future.get() 中长期用于指示子任务失败的封装器相同。异常原因信息会保留在 getCause() 中,因此可以直接沿用熟悉的 catch-then-switch 模式:
try (var scope = StructuredTaskScope.open()) { Subtask<String> user = scope.fork(() -> findUser(userId)); Subtask<List<Order>> o = scope.fork(() -> fetchOrders(userId)); scope.join(); return new Response(user.get(), o.get());} catch (ExecutionException e) { switch (e.getCause()) { case IOException ioe -> handleIo(ioe); case TimeoutException te -> handleTimeout(te); default -> throw e; }}这次变更缩小了经典并发代码与结构化作用域之间的概念差异。已经在早期预览版中捕获 FailedException 异常的团队,在迁移至 JDK 27 时,只需要将这些捕获语句更新为捕获 ExecutionException 异常。
第二个改动是结构上的。现在,StructuredTaskScope 和 Joiner 接口新增了第三个类型参数 R_X,用于表示 join() 可能抛出的异常类型。之前的签名是 Joiner
第三项更改是新增了一个 open 重载,它将默认的合并策略(即无参数 open() 的行为,它会等待所有子任务成功或任一子任务失败)与一个配置操作符(使用 UnaryOperator 设置作用域 的 Configuration )配对:
try (var scope = StructuredTaskScope.open( cfg -> cfg.withTimeout(Duration.ofSeconds(2)).withName("checkout"))) { scope.fork(() -> fetchCart(userId)); scope.fork(() -> fetchProfile(userId)); scope.join();}之前,如果要在默认的快速失败策略中应用超时、名称或自定义线程工厂,就必须在操作符中同时传入一个 Joiner。新的工厂方法消除了这一繁琐步骤。该重载接受一个 UnaryOperator
结构性保障保持不变:子任务会继承 ScopedValue 绑定(JEP 506),JSON 线程转储格式仍然会向工具暴露作用域层次结构,而且,当作用域在 try-with-resources 之外使用,或从非所有者线程分叉时,仍然会抛出 StructureViolationException 异常。
预览版 7 并非重新设计。预览版 5 中确定的 API 框架保持不变,本轮更改仅限于易用性和类型方面,而非结构。对于关注该 API 的团队而言,每次预览范围的缩小,都表明设计正在趋于稳定。结构化并发已经经历了两个孵化期和数个预览版。尽管 JEP 533 并未明确最终时间表,但该 API 似乎正在趋于稳定。
要对该提案进行测试,开发人员可以在 JDK 27 早期访问版本中使用 --enable-preview 启用该预览功能。在 API 最终确定之前,通过 OpenJDK 邮件列表收集的反馈意见将继续被用于完善该 API。





