其改进版——StructuredTaskScope。 5 StructuredTaskScope Java 21 Virtual Thread作为一项功能被引入,它在大多情况下实际上消除了阻塞问题。 StructuredTaskScope类知道提交的任务之间的关系,因此它可对它们进行更智能假设。 使用StructuredTaskScope的示例 在任一任务失败时,立即返回用例。 StructuredTaskScope美妙在于——若子线程创建自己的StructuredTaskScope(子任务本身有自己的子任务),取消时它们都会得到干净处理。 6 使用StructuredTaskScope 当一个用例需要将任务分解为子任务,可能还需将子任务进一步分解为更多子任务时,使用StructuredTaskScope是合适的。 但StructuredTaskScope远不止如此。
在当前提案中,唯一的显著变化是StructuredTaskScope::fork(…)方法返回一个[Subtask],而不是Future。 their results return new Response(user.get(), order.get()); } //... } 这段代码创建了一个新的StructuredTaskScope 要使用StructuredTaskScope API,开发人员必须启用预览 API 来编译该代码,如下面的命令所示: javac --release 21 --enable-preview Main.java 时,大多数情况下都不会直接使用StructuredTaskScope类,而是使用两个子类中的某一个,这两个子类均实现了关闭策略。 新的StructuredTaskScope为ExecutorService提供了一个更简单、更安全地替代方案。
The exact type is StructuredTaskScope, that's the name of the class. Live demo: a first StructuredTaskScope Suppose we want to query a weather forcast server. It;s a StructuredTaskScope instance. It has a parameter, which is going to be Weather. It is an extension of the basic StructuredTaskScope class, and is called the StructuredTaskScope.ShutdownOnSuccess But we can certainly extend StructuredTaskScope. So let's do that.
唯一重要变化是StructuredTaskScope::fork(...)方法返回一个[子任务],而不是一个Future,如下面所讨论的。 9 突破预览版限制StructuredTaskScope 是预览版 API,默认禁用。 一个子任务可以创建它自己的嵌套的 StructuredTaskScope 来分叉它自己的子任务,从而创建一个层次结构。 在运行时,StructuredTaskScope 强制执行结构和顺序并发操作。 实际上,大多数使用 StructuredTaskScope 的情况下,可能不会直接使用 StructuredTaskScope 类,而是使用下一节描述的两个实现了关闭策略的子类之一。
在当前提案中,唯一的显著变化是 StructuredTaskScope::fork(...) 方法返回一个 [Subtask],而不是 Future。这是一个预览特性。 their results return new Response(user.get(), order.get()); } //... } 这段代码创建了一个新的 StructuredTaskScope 要使用 StructuredTaskScope API,开发人员必须启用预览 API 来编译该代码,如下面的命令所示: javac --release 21 --enable-preview Main.java 时,大多数情况下都不会直接使用 StructuredTaskScope 类,而是使用两个子类中的某一个,这两个子类均实现了关闭策略。 新的 StructuredTaskScope 为 ExecutorService 提供了一个更简单、更安全地替代方案。
StructuredTaskScope.ShutdownOnSuccess:行为:一旦有任何一个子任务成功完成,作用域就会关闭,取消所有其他正在运行的子任务。 2.3自定义策略除了内置策略,开发者还可以通过继承StructuredTaskScope来实现自己的协调逻辑,以满足更复杂的业务需求。 所有的生命周期管理和错误处理都由StructuredTaskScope自动完成。第四章:高级特性与应用场景JEP525在第六次预览中还引入了一些增强功能。 例如,在JavaFlightRecorder(JFR)中,可以清晰地看到一个StructuredTaskScope事件及其包含的所有子任务,极大地提升了分布式追踪的能力。 5.3未来展望经过六轮预览,StructuredTaskScope的API已经非常稳定。它极有可能在下一个长期支持版本JDK29中成为正式特性。
结构化并发的基本 API 是`StructuredTaskScope`[17]。 StructuredTaskScope 支持将任务拆分为多个并发子任务,在它们自己的线程中执行,并且子任务必须在主任务继续之前完成。 StructuredTaskScope 的基本用法如下: 结构化并发非常适合虚拟线程,虚拟线程是 JDK 实现的轻量级线程。许多虚拟线程共享同一个操作系统线程,从而允许非常多的虚拟线程。 15] JEP 414: https://openjdk.java.net/jeps/414 [16] JEP 417: https://openjdk.java.net/jeps/417 [17] StructuredTaskScope download.java.net/java/early_access/loom/docs/api/jdk.incubator.concurrent/jdk/incubator/concurrent/StructuredTaskScope.html
该 API 以 java.util.concurrent.StructuredTaskScope 和 Joiner 抽象为中心,后者可以控制如何以及何时组合分叉子任务的结果。 现在,StructuredTaskScope.open() 的重载方法在接受配置修饰符时,预期参数类型已从 Function 改为 UnaryOperator。 try (var scope = StructuredTaskScope.open()) { var user = scope.fork(() -> fetchUser(userId)); class PartialCollector<T> implements StructuredTaskScope.Joiner<T, List<T>> { private final Queue <T> st) { if (st.state() == StructuredTaskScope.Subtask.State.SUCCESS) { results.add
让我们看一个例子: try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { Future<Shelter> shelter (); Response response = new Response(shelter.resultNow(), dogs.resultNow()); // ... }Copy 由于StructuredTaskScope StructuredTaskScope为我们提供了两个子类,它们有不同的用途。在本教程中,我们将使用ShutdownOnFailure(),它会在出现问题时关闭子任务。 StructuredTaskScope的使用与同步代码的结构非常相似。创建范围的线程是所有者。作用域允许我们在作用域中分叉其他子任务。此代码以异步方式调用。
JDK 25进行了一些API变更,StructuredTaskScope 现在通过静态工厂方法 而非公共构造函数进行初始化。 零参数的 open 工厂方法覆盖了常见场景,即创建一个 StructuredTaskScope 实例,用于等待所有子任务成功或任意子任务失败。 新的写法如下: Response handle() throws InterruptedException { try (var scope = StructuredTaskScope.open compose their results return new Response(user.get(), order.get()); } } 结构化并发 API 的核心类是 StructuredTaskScope StructuredTaskScope 将子任务的生命周期限制在一个清晰的作用域内,所有任务与子任务的交互(包括 fork、join、错误处理及结果组合)均在此作用域内完成 。 五.
开发人员可以使用 StructuredTaskScope 类来组织他们的并发代码,这个类将把一组子任务视为一个单元。子任务通过单独的线程创建,然后连接成一个单元,也可以作为一个单元进行取消。 Response handle() throws ExecutionException, InterruptedException { try (var scope = new StructuredTaskScope.ShutdownOnFailure 与 ExecutorService.submit() 一样,StructuredTaskScope.fork() 接受 Callable 作为参数,并返回 Future。 上面的例子使用了 StructuredTaskScope API,如果要在 JDK 19 上运行它们,必须添加 jdk.incubator.concurrent 模块,同时要启用预览功能来使用虚拟线程。
1.2核心API:StructuredTaskScopejava.util.concurrent.StructuredTaskScope是实现结构化并发的核心类。 2.3自定义StructuredTaskScope除了上述两种预定义策略,你还可以通过继承StructuredTaskScope来实现更复杂的协调逻辑,例如等待特定数量的任务成功,或者根据任务结果动态决定是否继续 第三章:与传统并发模型的对比维度传统并发模型(ExecutorService+Future)结构化并发(StructuredTaskScope)生命周期管理手动管理,极易出错和泄漏自动管理,作用域退出时自动清理错误处理分散 newStructuredTaskScope.ShutdownOnFailure()){//...并行调用多个服务...}}4.2避免在作用域外持有Subtask引用Subtask对象的生命周期与其所属的StructuredTaskScope
Java技术指南:https://www.java-family.cn StructuredTaskScope 结构化并发编程式(Structured Concurrent)和虚拟线程(Virtual 这里要介绍的第一个对象是Scope对象, 确切的类型是StructuredTaskScope。 public static Weather readWeather() throws Exception { // try-with-resource try(var scope = new StructuredTaskScope 通过fork()方法fork一个Callable类型的任务,fork()方法返回一个Future对象,我们调用join()方法阻塞调用,它将阻塞当前线程,直到所有提交(frok)给StructuredTaskScope 如果op已经创建了一个StructuredTaskScope但没有关闭它,那么退出op会导致在动态范围内创建的每个StructuredTaskScope被关闭。
结构化并发(JEP 505) 通过 StructuredTaskScope 管理多线程任务,确保子任务与父任务生命周期同步: try (var scope = new StructuredTaskScope
结构化并发 API 的主体类是StructuredTaskScope。此类允许开发人员将任务构建为一系列并发子任务,并将它们作为一个单元进行协调。 StructuredTaskScope将子任务或分叉的生命周期限制在明确的词法范围内,这样我们可以像写单线程代码一样来写多线程代码。 官方给来一个例子: Response handle() throws ExecutionException, InterruptedException { try (var scope = new StructuredTaskScope.ShutdownOnFailure
StructuredTaskScope 结构化并发编程式(Structured Concurrent)和虚拟线程(Virtual Threads)息息相关。 这里要介绍的第一个对象是Scope对象, 确切的类型是StructuredTaskScope。 public static Weather readWeather() throws Exception { // try-with-resource try(var scope = new StructuredTaskScope 通过fork()方法fork一个Callable类型的任务,fork()方法返回一个Future对象,我们调用join()方法阻塞调用,它将阻塞当前线程,直到所有提交(frok)给StructuredTaskScope 如果op已经创建了一个StructuredTaskScope但没有关闭它,那么退出op会导致在动态范围内创建的每个StructuredTaskScope被关闭。
Order> orders) {}static Profile loadProfile(long userId) throws Exception { try (var scope = new StructuredTaskScope.ShutdownOnFailure static String crawl(List<String> urls) throws Exception { try (var scope = new StructuredTaskScope.ShutdownOnFailure scope.join(); scope.throwIfFailed(); return tasks.stream() .map(StructuredTaskScope.Subtask
因此,我们可以使用结构化子任务来计算它们,如下所示: try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { Callable throws InterruptedException, ExecutionException, TimeoutException { try (var scope = new StructuredTaskScope.ShutdownOnSuccess Callable<T>> tasks) throws InterruptedException, ExecutionException { try (var scope = new StructuredTaskScope.ShutdownOnFailure 但是,如果我们代码的要点是通过副作用进行操作,那么就可以使用 StructuredTaskScope<Void>,即使用返回 void 的任务作用域,如本例所示: void serveScope(ServerSocket serverSocket) throws IOException, InterruptedException { try (var scope = new StructuredTaskScope
结构化并发示例public class Test { public static void main(String[] args) { try (var scope = new StructuredTaskScope.ShutdownOnFailure java.util.concurrent.ExecutionException: java.lang.Exception: testat jdk.incubator.concurrent/jdk.incubator.concurrent.StructuredTaskScope $ShutdownOnFailure.throwIfFailed(StructuredTaskScope.java:1188)at Test.main(Test.java:17)Caused by: java.lang.Exception
userRepository.findAll()); } // 使用结构化并发处理多个关联任务 public void processUserData() { try (var scope = new StructuredTaskScope.ShutdownOnFailure 创建轻量级线程自动适配现有ExecutorService和@Async注解显著提升高并发场景下的吞吐量(示例中处理10万任务快5-10倍)结构化并发(Structured Concurrency)使用StructuredTaskScope