← Back to Multithreading

Waiting for a Thread with join()

Learn how one thread can wait for another thread to finish its work.

1. A Simple Everyday Example

Imagine you are preparing dinner with your family.

You ask one person to prepare the vegetables and another person to prepare the dough.

You want to start cooking only after the vegetables are ready.

So, you wait for the person preparing the vegetables to finish before moving to the next step.

Something similar can happen in Java multithreading.

One thread may need to wait until another thread completes its work. Java provides a method called join() for this purpose.

2. What Is join()?

The join() method allows one thread to wait for another thread to finish.

Let's understand this with a simple example.

We have two threads:

  • Worker Thread: Performs some work.
  • Main Thread: Waits for the worker thread to finish.

We call join() on the worker thread from the main thread.

Thread worker = new Thread(() -> {
    System.out.println("Worker thread is working...");
});

worker.start();

worker.join();

System.out.println("Worker thread has finished.");

Here is what happens:

  1. We create the worker thread.
  2. We start the worker thread using start().
  3. The main thread calls worker.join().
  4. The main thread waits until the worker thread finishes.
  5. After that, the main thread continues executing.

The important point is that join() makes the calling thread wait for the thread on which join() is called.

3. Understanding the Execution Order

Let's look at a complete example.

public class JoinExample {

    public static void main(String[] args)
            throws InterruptedException {

        Thread worker = new Thread(() -> {
            System.out.println("Worker: Starting work");

            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                System.out.println("Worker was interrupted");
            }

            System.out.println("Worker: Work completed");
        });

        worker.start();

        System.out.println("Main: Waiting for worker");

        worker.join();

        System.out.println("Main: Continuing execution");
    }
}

Let's understand the output step by step.

Worker: Starting work
Main: Waiting for worker
Worker: Work completed
Main: Continuing execution

The worker thread starts its work and sleeps for two seconds. Meanwhile, the main thread prints its waiting message.

When the main thread reaches worker.join(), it waits for the worker thread to finish.

Once the worker completes its work, the main thread continues and prints the final message.

Notice that the main thread does not move beyond worker.join() until the worker thread finishes.

4. What Happens If We Don't Use join()?

Let's remove the join() call from the previous example.

worker.start();

System.out.println("Main: Continuing execution");

Now the main thread does not wait for the worker thread. It continues executing immediately after starting the worker.

The worker thread and main thread can perform their work independently.

This means the main thread may print its message before the worker thread finishes.

Remember:

  • With join(), the calling thread waits for the other thread to finish.
  • Without join(), the calling thread continues without waiting.

5. Does join() Stop All Threads?

No. This is an important point.

When the main thread calls worker.join(), only the main thread waits.

The worker thread continues doing its work. Other threads can also continue executing.

So, join() does not stop the worker thread. It simply makes the calling thread wait for the worker thread to finish.

6. Can join() Throw an Exception?

Yes. The join() method can throw InterruptedException.

This happens if the thread waiting inside join() is interrupted.

That is why our example used:

public static void main(String[] args)
        throws InterruptedException

We will understand interruption in more detail in our upcoming class.

For now, remember that Java requires us to handle InterruptedException when using join().

7. What Did We Learn?

  • join() allows one thread to wait for another thread to finish.
  • The thread calling join() is the one that waits.
  • The thread on which join() is called continues its work.
  • Without join(), the calling thread does not wait.
  • join() can throw InterruptedException.

Think of join() as saying: "I will continue only after you finish your work."

Test Your Understanding

Let's check what you have learned. Select one answer for each question.

1. What is the purpose of join() in Java?

2. Consider worker.join() being called from the main thread. Which thread waits?

3. What happens to the worker thread when the main thread calls worker.join()?

4. What happens if we do not call join()?

5. Which exception can join() throw?

Class Summary

Let's quickly revise what we learned in this class.

  • The join() method makes one thread wait for another thread to finish.
  • The thread that calls join() is the thread that waits.
  • The thread on which join() is called continues its execution.
  • Without join(), the calling thread does not wait for the other thread to finish.
  • join() can throw InterruptedException.

Remember: join() means waiting for another thread to finish its work.

What's Next?

Class 9: Interrupting a Thread

We have learned how one thread can wait for another thread. But what if we want to request a thread to stop waiting or respond to an interruption?

In the next class, we will learn about the interrupt() method and how Java handles thread interruption.

See you in the next class!

0% Completed

You have completed 8 out of 46 classes.