Java – recursively cancel alloff completable future

If I had

CompletableFuture<Something> future1 = service.request(param1);
CompletableFuture<Something> future2 = service.request(param2);
CompletableFuture<Void> many = CompletableFuture.allOf(future1,future2);

When I do many What happens when you cancel()? Will future1 and future2 also be cancelled? If not, what is the easiest way? I don't want to stick to future 1 and future 2, just to be able to cancel them when many are cancelled

Some background on why I do this: when receiving a piece of data, I need to request matching, possibly future data to perform the calculation If updated data arrives, I want to cancel the completion of the previous calculation, because the result will be immediately replaced by the new calculation

Solution

Before you make life difficult, you should know what canceling completable future actually does Most importantly, it does not stop related calculations

If the calculation associated with completable future has been run but not completed, canceling completable future will convert it to the "cancelled" state, which may have a direct impact on all relevant stages, but will not affect the calculation, which will continue until completion, although it attempts to complete the cancellation in the future

Although other future may be cancelled by interrupt, this will stop the calculation. If it checks for interrupt, this does not apply to completable future. See completable future cancel(boolean):

Therefore, when you successfully cancel future1 or future2, the only direct effect is to cancel many. You can also call many cancellations themselves If there are more dependency phases, it will have a wider impact, but since you said you don't want to keep references to future1 or future2, that doesn't seem to be the case

The following code demonstrates this behavior:

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);

This code reproduces printing:

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

(order may change)

Whether you call supply Cancel (true) or then Cancel (true), or call true or false; It will not prevent ongoing supplier evaluation

If the relevant calculation has not yet started and it checks the cancellation status at startup, it will be different, just like the operation generated by the convenient method in completable future This is a rare situation. Usually, your service The request (paramn) call should trigger the evaluation

As its name indicates, it is a basic attribute of completable future. It is completable, that is, anyone can call complete on it. Therefore, completable future cannot control anyone who may eventually call complete in the future Therefore, cancellation can be achieved by setting it to the cancel state, which means ignoring subsequent completion attempts and propagating the cancellation down to dependent operations

So the most important thing is that you may have done well. Just call cancel on many instances, because calling cancel on future1 and future2 is unlikely to produce an effect worthy of code complexity

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>