其改进版——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.
该 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
唯一重要变化是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
让我们看一个例子: 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
结构化并发(JEP 505) 通过 StructuredTaskScope 管理多线程任务,确保子任务与父任务生命周期同步: try (var scope = new 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被关闭。
结构化并发 API 的主体类是StructuredTaskScope。此类允许开发人员将任务构建为一系列并发子任务,并将它们作为一个单元进行协调。 StructuredTaskScope将子任务或分叉的生命周期限制在明确的词法范围内,这样我们可以像写单线程代码一样来写多线程代码。 官方给来一个例子: Response handle() throws ExecutionException, InterruptedException { try (var scope = new StructuredTaskScope.ShutdownOnFailure
因此,我们可以使用结构化子任务来计算它们,如下所示: 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
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
结构化并发示例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
四、深度进阶:虚拟线程如何与Project Loom配合 4.1 结构化并发(Structured Concurrency) JDK 21引入的StructuredTaskScope让并发任务的生命周期与作用域绑定 : java try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { Future<String> user = scope.fork