Futures
Futures are a complex, heterogeneous feature. Each language handles them slightly differently. Most of the discussion here is for Java.
A future has 3 parties involved in the lifecycle.
- The Scheduler. This party (thread) usually creates the future object. The scheduler is the one that sets up the fulfillment of the future.
- The Fulfiller. This party does the work necessary to fill in the future results or errors. Usually this party is different from the Scheduler, but not always.
- The Waiter. This party (possibly multiple threads), awaits the results set by the Fulfiller.
In a typical scenario, these three parties are different threads, meaning there is a high amount of coordination between them. In Java syntax:
Future<String> future = CompletableFuture.supplyAsync(() -> "a" + "b", executor); future.get();
The party that creates the CompletableFuture object is the Scheduler. It is the current thread. The Fulfiller is the executor, which is likely a ThreadPoolExecutor, or a Virtual Thread executor. It will actually be running the provided lambda, and completing the future. Finally, the current thread is acting as the Waiter. It does so by calling get(), which puts it to sleep until the Fulfiller wakes it up.
