How does the jvm return a Future object reference before the asynchronous method has completed

61 Views Asked by At

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.

1

There are 1 best solutions below

2
Jorn On

In the code you've shown, you only create the Future after helloFuture has finished executing. There is no magic going on there: The method runs in exactly the order you think it does by reading the code. The method uses CompletableFuture.completedFuture, which does exactly what you think: It returns a new Future instance in an already-completed state. And the helloFuture call in the Test class will block until all of that is done.