Have you wonder how CompletableFuture.supplyAsync works and how it allows for asynchronous execution of tasks, which can help improve performance and handle high rates of calls to a method that performs time-consuming operations.
When you call CompletableFuture.supplyAsync() with a Supplier function as an argument, the execution of that function will start immediately on a separate thread from the ForkJoinPool.commonPool() (unless you provide a different executor).
The supplyAsync() method returns a new CompletableFuture that represents the result of the asynchronous computation. The result of the Supplier function is computed in the background and is made available through this CompletableFuture once it is completed.
So, any code that comes after the call to supplyAsync() will be executed immediately on the calling thread, while the execution of the Supplier function will start concurrently on a separate thread. Once the Supplier function completes its execution, the CompletableFuture returned by supplyAsync() will be completed with the result of the function.
Note that calling CompletableFuture.supplyAsync() does not necessarily mean that the computation will be executed immediately. If the default ForkJoinPool.commonPool() is already saturated with other computations, the new computation will be queued and may not start executing immediately. In this case, you can provide a custom executor to supplyAsync() to ensure that the computation will start executing as soon as possible.