如何知道Java 19 Structured Concurrency StructuredTaskScope是否已关闭(取消)?

xeufq47z  于 2023-04-28  发布在  Java
关注(0)|答案(2)|浏览(134)

Java 19 ShutdownOnFailure作用域还允许使用shutdown方法显式取消所有任务。如何知道示波器是否已关闭?该API包含isShutdown方法,但它是私有的。
这里有一些(不完整的)代码,只是为了说明一个可能的用法,其中一个作用域在启动一段时间后被所有者调用shutdown取消。
我想在join()之后,我可以发出另一个作用域。fork()并检查是否返回一个被取消的任务的未来,但这看起来很奇怪。就这么走吗?

ExecutorService executor = Executors.newCachedThreadPool();
try (StructuredTaskScope.ShutdownOnFailure scope = new StructuredTaskScope.ShutdownOnFailure()) {
    Future<Integer> numOrders = scope.fork(Business::getNumItemsFromRequest);
    Future<Double> price = scope.fork(Business::getPriceFromDB);
    
    Business.sleepFor(500);
    scope.shutdown(); // cancels all the scope tasks
    //numOrders.cancel(true); // cancel just one task
    
    scope.join(); // wait for all tasks
    try {
        scope.throwIfFailed();
        // how would I know if scope was shutdown before all tasks completed?
        System.out.println("Scope Completed Without Errors ( But possibly canceled ) ");
        double amount = numOrders.get() * price.get();
ergxz8rk

ergxz8rk1#

建议:将你需要的功能封装在一个子类中。
来自培养箱文档:
https://download.java.net/java/early_access/loom/docs/api/jdk.incubator.concurrent/jdk/incubator/concurrent/StructuredTaskScope.html

扩展结构化任务范围

可以扩展StructuredTaskScope,并覆盖handleComplete,以实现ShutdownOnSuccess和ShutdownOnFailure所实现的策略之外的策略。该方法可以被覆盖以例如收集以结果完成的子任务的结果并且忽略失败的子任务。当子任务失败时,它可能会收集异常。它可以调用shutdown方法来关闭并在出现某些情况时使join唤醒。
子类通常会定义一些方法,以使结果、状态或其他结果对在联接方法之后执行的代码可用。收集结果并忽略失败的子任务的子类可以定义返回结果集合的方法。实现当子任务失败时关闭的策略的子类可以定义检索第一个失败的子任务的异常的方法。

ctehm74n

ctehm74n2#

工作代码(作为实验)位于here
鉴于此:

var result = "error";

try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
     var numOrders = scope.fork(() -> taskGetNumItemsFromRequest()); 
     var price = scope.fork(() -> taskGetPriceFromDB());

    if (doShutdown) {
        scope.shutdown();
    }
            
    scope.join();          
    scope.throwIfFailed();

    result = numOrders.resultNow() + " " + price.resultNow();
} catch (Exception ex) {
    if (ex != null) {
        System.err.println("caught ex: " + ex.getClass());
        System.err.println("caught ex message: " + ex.getMessage());
    }
}

然后这一行:

result = numOrders.resultNow() + " " + price.resultNow();

如果作用域关闭,将抛出一个Exception。Future.resultNow()See the code
不清楚是否要区分其他异常情况,例如 * 关闭 * 作用域,或子任务引发的异常?如果你真的想区分,解释问题中的原因会有所帮助(即:最终目标)。
一般来说,应该有两条路径:result的happy-path,然后是抛出异常的路径(无论出于何种原因)。

相关问题