How to make main thread wait for all child threads finish?
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
Making the main thread wait for worker threads is a standard synchronization task. The simplest version is to start several threads, let them do their work, and then block the main thread until they all finish, but the best implementation depends on whether you created raw threads directly or you are using a thread pool or task framework.
The Classic Answer: join()
When you own the Thread objects directly, the usual solution is join(). It blocks the calling thread until the target thread completes.
Here is a basic Java example:
The main thread reaches the final print only after all three workers are done.
Why join() Works Well
join() is straightforward when:
- the number of child threads is small
- you created them manually
- the control flow is simple
It is easy to read and perfectly appropriate for many programs. The main limitation is that it does not scale gracefully to more complex orchestration patterns.
Waiting for Many Tasks with Executors
If you are using a thread pool, waiting on raw thread objects is often the wrong abstraction. A better pattern is to submit tasks and wait on Future objects:
This is often cleaner because the waiting logic matches the task abstraction already used by the codebase.
Coordination Tools Beyond join()
Other synchronization tools exist for more complex cases:
- '
CountDownLatchwhen several workers must signal completion' - '
CyclicBarrierwhen threads must meet at a common phase' - '
CompletableFuture.allOf()for asynchronous task composition'
For example, CountDownLatch is useful when child threads are created in different parts of the program and the main thread needs a single "all done" signal.
Timeouts and Failure Handling
Waiting forever is often a bad default. Threads can deadlock, block on I/O, or fail silently. If the application cannot tolerate indefinite blocking, use timeouts:
For executor-based code, use bounded waits or cancellation-aware patterns. Also decide what "finished" means when a child thread throws an exception. Completion and success are not the same thing.
Common Pitfalls
The biggest mistake is starting threads and then assuming they will finish before the main thread exits. Without explicit waiting, the program may terminate early or continue before results are ready.
Another mistake is joining from the wrong place. If a UI thread or request thread blocks unnecessarily, the application can become unresponsive.
People also forget interruption handling. If join() is interrupted, the code should usually restore the interrupt status or handle shutdown deliberately.
Finally, if you are already using a high-level concurrency API, avoid dropping down to raw thread management unless there is a real reason. Mixing abstractions often makes code harder to maintain.
Summary
- Use
join()when you created raw child threads and want the main thread to wait for them. - Use executor or task-based waiting when the program already uses a thread pool.
- Consider latches or futures for more complex coordination.
- Prefer bounded waits when indefinite blocking is risky.
- Waiting for completion is simple, but handling failure and cancellation correctly is just as important.
Related reading
- How to make make a .NET COM object apartment-threaded?
- How to make my code run on multiple cores?
- How to make OleDb code run asynchronous?
- how to make oracle UTL_HTTP.request asynchronous?
- How to make parallel calls in Erlang and wait for all of the results?
- how to make synchronous call to indexeddb method from javascript
- how to make synchronous http calls within async.each in nodejs
- How to make this asynchronous? async, await - C, MVC
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.