JEP 428:针对JDK 19提出的结构化并发


Java开发人员通过将任务分解为多个子任务来管理复杂性。在普通的单线程代码中,子任务按顺序执行。但是,如果子任务彼此足够独立,并且有足够的硬件资源,则可以通过并发执行子任务来使任务运行得更快(延迟更低) 。例如,如果每个 I/O 操作都在自己的线程中执行,则由多个 I/O 操作的结果组成的任务将运行得更快。

虚拟线程的可用性使得将线程专用于每个 I/O 操作具有成本效益。

通过引入结构化并发库来简化多线程编程。结构化并发将在不同线程中运行的多个任务视为单个工作单元,从而简化错误处理和取消,提高可靠性并增强可观察性。

目标

  • 提高多线程代码的可靠性和可观察性。
  • 提倡一种并发编程风格,可以消除取消和关闭带来的常见风险,例如线程泄漏和取消延迟。

结构化并发是一种多线程编程方法,它保留了单线程代码开发人员所享有的可读性和可维护性。它的原理是,如果一个任务拆分成并发的子任务,它们都返回到同一个地方:任务的代码块。

Response handle() throws ExecutionException, InterruptedException {
    try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
        Future<String>  user  = scope.fork(() -> findUser()); 
        Future<Integer> order = scope.fork(() -> fetchOrder());

        scope.join();          // Join both forks
        scope.throwIfFailed();
// ... and propagate errors

       
// Here, both forks have succeeded, so compose their results
        return new Response(user.resultNow(), order.resultNow());
    }
}

在所有条件下,生命周期都被限制在一个词法范围内:try-with-resources 的主体。