Future.get() makes you wait

Read the explanation
What if

submit() gives you a Future right away. get() trades it for the result, and blocks until the result exists.

01234567submit()doOtherWork()f.get(): WAITINGprintlnslowCall()

Tap any block to see what that thread is doing.

  • Running
  • Waiting / parked
  • Waiting on I/O
Step 1/4

submit() hands slowCall() to the pool and returns a Future at once.

1ExecutorService pool = Executors.newSingleThreadExecutor();2Future<String> f = pool.submit(() -> slowCall()); // returns right away3doOtherWork();                                    // main is still free4String result = f.get();                          // main blocks here5System.out.println(result);6pool.shutdown();

Explanation

What just happened

submit() returned a Future straight away, and main kept working. When main called f.get(), the result wasn’t ready, so main parked (WAITING) until the pool thread finished slowCall().

Try the what-if switch

get() too early: calling get() straight after submit() makes main wait at once, and doOtherWork() can only start after slowCall(). The code still uses a pool, but nothing overlaps, so it’s as slow as doing both in a row.

A Future is a receipt

Think of it like a ticket at a coffee counter. You get it at once, and you can do other things. get() is walking to the counter and standing there until your order is ready.

Use it well

String result = f.get(2, TimeUnit.SECONDS); // throws TimeoutException

Its limits

With a plain Future, the only way to use the result is to block on it. You can’t say “when this is done, do that”. That’s what CompletableFuture adds, in the next scenarios.

Common questions

Does Future.get() block?

Yes. If the result isn't ready, get() parks the calling thread (WAITING) until the task finishes.

Why isn't my ExecutorService code any faster?

If you call get() right after submit(), the caller waits at once and nothing overlaps. Start slow work as early as you can and call get() as late as you can.

How do I add a timeout to Future.get()?

Use get(2, TimeUnit.SECONDS). It throws TimeoutException when time runs out, so a stuck task can't freeze the caller forever.

Verified: this timeline matches a real program, checked in CI on JDK 21 and 25. How we verify. Unclear or wrong? Tell us