首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我如何知道Java19结构化并发StructuredTaskScope是否被关闭(取消)?

我如何知道Java19结构化并发StructuredTaskScope是否被关闭(取消)?
EN

Stack Overflow用户
提问于 2022-11-16 17:15:28
回答 2查看 38关注 0票数 3

JDK 19 ShutdownOnFailure作用域还允许使用关机方法显式取消所有任务。我如何知道范围是否已关闭?API包括一个isShutdown方法,但它是私有的。

下面是一些(不完整的)代码,只是为了说明可能的用法,其中一个作用域在所有者调用关机启动一段时间后被取消。

我猜想,在join()之后,我可以发出另一个scope.fork(),并检查是否返回一个已取消的任务的未来,但这似乎很奇怪。这就是该走的路吗?

代码语言:javascript
复制
    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();
EN

回答 2

Stack Overflow用户

发布于 2022-11-16 17:28:29

建议:将所需的功能封装在子类中。

来自Incubator文档:

access/loom/docs/api/jdk.incubator.concurrent/jdk/incubator/concurrent/StructuredTaskScope.html 扩展StructuredTaskScope 可以扩展StructuredTaskScope,并重写handleComplete,以实现ShutdownOnSuccess和ShutdownOnFailure实现的策略以外的策略。该方法可能被重写,例如,收集带有结果的子任务的结果,而忽略失败的子任务。当子任务失败时,它可能收集异常。它可能会调用关机方法来关闭,并在某些情况出现时导致连接唤醒。 子类通常将定义方法,以使在join方法之后执行的代码可用结果、状态或其他结果。收集结果并忽略失败的子任务的子类可能定义返回结果集合的方法。当子任务失败时,实现要关闭的策略的子类可以定义一个方法来检索要失败的第一个子任务的异常。

票数 3
EN

Stack Overflow用户

发布于 2022-11-23 13:27:44

工作代码(作为实验)定位这里

鉴于此:

代码语言:javascript
复制
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());
    }
}

然后这一行:

代码语言:javascript
复制
    result = numOrders.resultNow() + " " + price.resultNow();

如果作用域被关闭,将引发异常。见代码 for Future.resultNow().

还不清楚是否要区分其他异常情况,例如关闭作用域,还是子任务引发的异常?如果你确实想要区分,这将有助于解释问题中的原因(即最终目标)。

通常,应该有两条路径:result的愉快路径和抛出异常的路径(无论出于什么原因)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74464598

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档