Home > database >  Shouldn't CompletableFuture.get(timeout) kill the task?
Shouldn't CompletableFuture.get(timeout) kill the task?

Time:12-01

I'm running two instances of CompletableFuture, which wait 1 second and print something to the console. The first one I interrupt after 0.5 seconds. So I expect only the second one to print, but in fact both do. What's going on here?

Here's the code:

CompletableFuture<Void> c1 = CompletableFuture.runAsync(() -> {
    System.out.println("Start CF 1");
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
    System.out.println(1);
});

CompletableFuture<Void> c2 = CompletableFuture.runAsync(() -> {
    System.out.println("Start CF 2");
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
    System.out.println(2);
});

long start = System.currentTimeMillis();
try {
    c1.get(500, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
    System.out.println("CF interrupted after "   (System.currentTimeMillis() - start)   "ms");
}
c2.get();

And it prints:

Start CF 1
Start CF 2
CF interrupted after 510ms
2
1

CodePudding user response:

No.

You can interrupt the completable future when you catch the TimeOutException exception using c1.cancel(true)

This way the developer can handle the time-out the way they prefer for the their use case.

CodePudding user response:

Why do you think it should? What if 2 consumers want to handle the result of the same future, and one is prepared to wait longer than the other? The first would kill it for the second, which it might've completed in time for.

In any case, Java doesn't have the concept of killing a task. The best you can do is set a flag asking it to stop - an interrupt - but that relies on the task checking and respecting the flag. Your tasks do, since Thread.sleep() implicitly checks the interrupt flag, but it's a contrived example, and a lot of tasks wouldn't ever check it.

  • Related