JDK 19 ShutdownOnFailure作用域还允许使用关机方法显式取消所有任务。我如何知道范围是否已关闭?API包括一个isShutdown方法,但它是私有的。
下面是一些(不完整的)代码,只是为了说明可能的用法,其中一个作用域在所有者调用关机启动一段时间后被取消。
我猜想,在join()之后,我可以发出另一个scope.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();发布于 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方法之后执行的代码可用结果、状态或其他结果。收集结果并忽略失败的子任务的子类可能定义返回结果集合的方法。当子任务失败时,实现要关闭的策略的子类可以定义一个方法来检索要失败的第一个子任务的异常。
发布于 2022-11-23 13:27:44
工作代码(作为实验)定位这里。
鉴于此:
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();如果作用域被关闭,将引发异常。见代码 for Future.resultNow().
还不清楚是否要区分其他异常情况,例如关闭作用域,还是子任务引发的异常?如果你确实想要区分,这将有助于解释问题中的原因(即最终目标)。
通常,应该有两条路径:result的愉快路径和抛出异常的路径(无论出于什么原因)。
https://stackoverflow.com/questions/74464598
复制相似问题