Consider the following code
class Test {
public void method1() {
CompletableFuture<String> future = helloFuture();
assertEquals("done", future.get());
}
}
class Service {
@Async
public CompletableFuture<String> helloFuture() throws InterruptedException {
System.out.println("hello future");
Thread.sleep(100);
return CompletableFuture.completedFuture("done");
}
}
The helloFuture method only returns the CompletableFuture in the last line after it has done its work. But we get a reference to the returned CompletableFuture in the test method when the helloFuture starts executing and start to wait for it in the main thread (using the get method). So how does the calling method get a reference to the CompletableFuture even before it is created in the helloFuture method?
This is in the context of Spring, but even for regular ExecutorService.submit I have the same question. I guess it is possible that in a regular ExecutorService the internal implementation first creates and returns a Future object in the calling thread and queues up the task to be executed in the thread pool.
InterruptedExceptionaside, it’s equivalent toCompletableFuture<String> future = CompletableFuture.completedFuture(new Service()) .thenComposeAsync(Service::helloFuture);