I seem to fail miserably at an apparently simple example with CompletableFuture
.
I have a CompletableFuture
that is blocked in a different thread, something like:
Supplier<CompletableFuture<String>> one = () -> CompletableFuture.supplyAsync(() -> {
System.out.println("started cf");
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(3));
System.out.println("done cf");
return "";
});
ExecutorService service = Executors.newSingleThreadExecutor();
service.submit(() -> {
try {
future = one.get();
future.get();
} catch (Exception e) {
System.out.println("caught");
future.completeExceptionally(e);
}
});
I want to be able to cancel
it, and then join
to wait until it is completed in a thread that is different then the one above, so something like this:
static CompletableFuture<String> future;
public static void main(String[] args) {
Supplier<CompletableFuture<String>> one = () -> CompletableFuture.supplyAsync(() -> {
System.out.println("started cf");
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(3));
System.out.println("done cf");
return "";
});
ExecutorService service = Executors.newSingleThreadExecutor();
service.submit(() -> {
try {
future = one.get();
future.get();
} catch (Exception e) {
System.out.println("caught");
future.completeExceptionally(e);
}
});
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
future.cancel(true);
System.out.println("before join");
String s = future.join();
System.out.println("s value : " + s);
System.out.println("done");
}
To my surprise, this one String s = future.join();
blocks and I don’t understand why.
More surprising, if I change my code to (instead of String s = future.join();
):
String s = null;
try {
s = future.join();
} catch(Exception e) {
System.out.println("here : " + e.getClass());
}
this one does not block. Can someone please shed some light here?