如何判断Java 19 StructuredTaskScope是否已关闭(取消)?
Java 19 ShutdownOnFailure作用域:判断是否提前关闭的正确方式
由于ShutdownOnFailure的isShutdown()是私有方法,无法直接调用,但要判断调用shutdown()后作用域是在所有任务完成前就终止,还是等任务全部完成后才结束,可以通过跟踪任务完成状态的方式实现,具体方案如下:
核心思路
在调用shutdown()之前,原子性地统计已完成的任务数量,对比总任务数:如果已完成数小于总任务数,说明调用shutdown()时还有任务在运行,作用域属于提前关闭;反之则是所有任务完成后才触发的关闭。
代码示例
import java.util.concurrent.StructuredTaskScope; import java.util.concurrent.atomic.AtomicInteger; public class ShutdownOnFailureDemo { public static void main(String[] args) throws InterruptedException { int totalTasks = 2; AtomicInteger completedTasks = new AtomicInteger(0); Object lock = new Object(); // 用于同步计数与shutdown操作 try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { // 提交任务,在finally块中更新完成计数 scope.fork(() -> { try { // 模拟任务执行逻辑 Thread.sleep(1000); return "Task 1 done"; } finally { synchronized (lock) { completedTasks.incrementAndGet(); } } }); scope.fork(() -> { try { // 模拟任务执行逻辑 Thread.sleep(2000); return "Task 2 done"; } finally { synchronized (lock) { completedTasks.incrementAndGet(); } } }); // 原子性获取已完成任务数并调用shutdown int completedBeforeShutdown; synchronized (lock) { completedBeforeShutdown = completedTasks.get(); scope.shutdown(); } // 等待所有任务结束 scope.join(); // 判断是否提前关闭 if (completedBeforeShutdown < totalTasks) { System.out.println("作用域在任务完成前已关闭"); } else { System.out.println("所有任务完成后才关闭作用域"); } } } }
为什么不推荐"提交新任务判断"的方式
尝试提交新任务到已shutdown的作用域会抛出IllegalStateException,但这种方式只能证明作用域已关闭,无法区分是任务全部完成后关闭还是任务未完成时提前关闭,因此无法满足需求。
注意事项
- 使用锁同步计数与
shutdown()调用,避免竞态条件(比如获取计数后、调用shutdown前有任务完成)。 - 不要依赖反射调用私有
isShutdown()方法,私有API属于内部实现,后续Java版本可能会变更,导致代码兼容性问题。
内容的提问来源于stack exchange,提问作者Gonen I
相关产品推荐
相关产品推荐

