Card 04/ 09

ConceptDifficulty: Intermediate1 min

Future.get(): Why Calling It Too Early Removes the Overlap

get blocks the calling thread, so submit everything before collecting anything.

Submitting a task returns a Future, a handle to a result that is not ready yet, and get() on it blocks: the calling thread stops until the result is ready. Where you call get() decides whether your tasks run at the same time or one after another.

Four tasks submitted to a pool and four results collected can take as long as the slowest task, or as long as all four together, depending on where one line goes:

java
for (Path file : files) {
    long rows = pool.submit(() -> countRowsIn(file)).get();
    total += rows;
}
submits one and waits for it before submitting the next: no overlap at all

Calling get() in the same statement as submit means nothing new is ever submitted while something else is running. The pool has four threads, and three of them sit idle.

java
List<Future<Long>> futures = files.stream()
        .map(f -> pool.submit(() -> countRowsIn(f)))
        .toList();

for (Future<Long> f : futures) {
    total += f.get();
}

Submit everything first, then collect. All four tasks are queued before any result is wanted, so the pool can run them at once, and the waiting happens at the end.

So submit and get are two halves of one operation, and they belong at two ends of the code. Putting them on one line turns a pool back into a sequence.