java – 递归取消allOff CompletableFuture

前端之家收集整理的这篇文章主要介绍了java – 递归取消allOff CompletableFuture前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
如果我有
CompletableFuture<Something> future1 = service.request(param1);
CompletableFuture<Something> future2 = service.request(param2);
CompletableFuture<Void> many = CompletableFuture.allOf(future1,future2);

当我做many.cancel()时会发生什么? future1和future2也会被取消吗?如果没有,最简单的方法是什么?我不愿意坚持未来1和未来2,只是为了能够在取消许多时取消它们.

关于我为什么要这样做的一些背景:当接收一条数据时,我需要请求匹配的,可能未来的数据来执行计算.如果有更新的数据到达,我想取消先前计算的完成,因为结果将立即被新计算取代.

解决方法

在你让生活变得艰难之前,你应该知道取消CompletableFuture实际上做了什么.最重要的是,它不会停止相关的计算.

如果与CompletableFuture相关联的计算已经运行但尚未完成,则取消CompletableFuture会将其转换为“已取消”状态,这可能对所有相关阶段产生直接影响,但不会影响计算,这将持续到完成,虽然它试图完成取消的未来将不会有任何影响.

虽然其他Future可能会被中断取消,这将停止计算,如果它检查中断,这不适用于CompletableFuture,请参阅CompletableFuture.cancel(boolean)

Parameters:

mayInterruptIfRunning – this value has no effect in this implementation because interrupts are not used to control processing.

因此,当您成功取消future1或future2时,唯一的直接影响是取消许多,您也可以通过调用许多本身取消来实现.如果有更多的依赖阶段会产生更广泛的影响,但是既然你说过,你不想保留对future1或future2的引用,那么情况似乎并非如此.

以下代码演示了该行为:

CompletableFuture<String> supply = CompletableFuture.supplyAsync(() -> {
    LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(2));
    System.out.println("supplying value");
    return "foo";
});
CompletableFuture<String> then = supply.thenApply(s -> {
    System.out.println("Evaluating next stage");
    return s;
});
CompletableFuture<?> last = then.handle((s,t) -> {
    System.out.println("last stage: value: "+s+",throwable: "+t);
    return "";
});
System.out.println("cancelling: "+supply.cancel(true));
ForkJoinPool.commonPool().awaitQuiescence(1,TimeUnit.DAYS);

代码可重现打印:

last stage: value: null,throwable: java.util.concurrent.CompletionException: java.util.concurrent.CancellationException
canceling: true
supplying value

(订单可能会改变)

无论你是调用supply.cancel(true)还是then.cancel(true),还是调用true或false;它不会阻止正在进行的供应商评估.

如果相关计算尚未开始并且它在启动时检查取消状态,则会有所不同,就像CompletableFuture中的便捷方法所产生的操作一样.这是一种罕见的情况,通常,您的service.request(paramN)调用应该触发评估.

正如其名称所示,它是CompletableFuture的一个基本属性,它是可完成的,即任何人都可以在其上调用complete,因此,CompletableFuture无法控制将来可能最终调用完成的任何人.因此,取消可以实现的是将其设置为取消状态,这意味着忽略后续完成尝试并将取消向下传播到依赖操作.

所以最重要的是你可能已经很好,只需在很多实例上调用cancel,因为在future1和future2上调用cancel不太可能产生值得代码复杂化的效果.

猜你在找的Java相关文章