Java Thread Join: Join() Method with Example

The join() method in Java is used when a thread needs to wait for another thread to finish its execution.

In other words, this method is used to wait for the current thread until the thread that has called the join() method completes its execution.

The join() method is an instance method, and it is always called by an object of Thread class. The general syntax to call join() method in Java program is as follows:

ThreadName.join(); // ThreadName is a reference variable of Thread class.

Calling join() method halts the execution of current thread (calling thread) until the ThreadName thread completes its execution (normal or abnormal termination). This means that the current thread will wait until the called thread completes its execution. Look at the below figure.

Java thread join() method

Different Forms of Join Method in Java


Thread class provides join() method in three flavors in Java. The general form of join() method is given below:

final void join() throws InterruptedException

Two other overloaded versions of join() method of Thread class take timeout arguments. The general forms of overloaded version of join() method in java are as follows:

public final void join(long milliseconds)
public final void join(long millisecond, nanoseconds)

If we use join() method with timeout, the caller thread will wait until the thread on which it is called, is terminated or the time limit has elapsed.


This method throws an exception named InterruptedException when it is interrupted while waiting to join. Therefore, it must be enclosed in a Java try-catch block.

Example Program based on join() Method


Let’s take an example program where we will call join() method inside the main method through Thread t. The main method will wait for thread t to end until thread t completes execution. Look at the program code for better understand.

Example 1:

public class X implements Runnable {
public void run()
{
   System.out.println("Child thread is running");
   for(int i = 1; i <= 4; i++)
   {
     System.out.println("I: " +i);
   }
   System.out.println("Child thread is ending");
}
public static void main(String[] args)
{
   X x = new X();
   Thread t = new Thread(x);
   t.start(); // thread t is ready to run.

// join() method is called inside the main thread (current thread) through Thread t.
   try
   {
      t.join(); // Wait for thread t to end.
   }
   catch(InterruptedException ie)
   {
     ie.printStackTrace();
   } 
   System.out.println("Main Thread is ending");
 }
}
Output:
       Child thread is running
       I: 1
       I: 2
       I: 3
       I: 4
       Child thread is ending
       Main Thread is ending

Explanation:

In the above example program, join() method is called inside the main thread through Thread t. Hence, the main thread (current thread) is going to wait until the thread t completes its execution and is terminated.


Let’s take another example program based on the join() method.

Example 2:

public class X implements Runnable {
public void run()
{
   System.out.println("Child thread is running");
   for(int i = 1; i <= 4; i++)
   {
      System.out.println("I: " +i);
      try 
      {
         Thread.sleep(2000); // Pauses the execution of child thread for 2 sec.
      }catch (InterruptedException e) {
         e.printStackTrace();
      }
   }
   System.out.println("Child thread is ending");
}
public static void main(String[] args) 
{
   X x = new X();
   Thread t = new Thread(x);
   t.start(); // thread t is ready to run.

// join() method is called inside the main thread (current thread) through Thread t. 
   try
   {
     t.join(1000); // Wait for thread t to end till 1 sec.
   }
   catch(InterruptedException ie)
   {
     ie.printStackTrace();	
   }
   System.out.println("Main Thread is ending");
  }
}

Output:
      Child thread is running
      I: 1
      Main Thread is ending
      I: 2
      I: 3
      I: 4
      Child thread is ending

Explanation:

1. In the above program, we have called the overloaded version of join() method inside the main thread that takes a timeout argument of 1 sec.

2. Inside run() method, when sleep() method is executed inside for loop, JVM pauses the child thread for 2 sec.

3. Meanwhile, join() method inside the main thread will wait only for 1 sec. When 1 sec is elapsed, Thread scheduler selects the main thread for its execution because child thread is paused for 2 sec.

4. When 2 sec is ended, the scheduler again selects the child thread to its complete execution.


Example 3:

public class A implements Runnable {
public void run()
{
  System.out.println("Child thread1 starts running");	
  for(int i = 1; i <= 3; i++)
  {
    System.out.println("I: " +i);	 
  }
  System.out.println("Child thread1 is ending");
 }
}
public class B implements Runnable {
public void run()
{	
   System.out.println("Child thread2 starts running");
   for(int j = 1; j <= 3; j++)
   {
     System.out.println("J: " +j);
   }
   System.out.println("Child thread2 is ending"); 
  }
}
public class Joining {
public static void main(String[] args) throws InterruptedException 
{
   A a = new A();
   Thread t1 = new Thread(a);	
 
   B b = new B();
   Thread t2 = new Thread(b);
 
   t1.start(); // thread t1 is ready to start.
   t1.join(); // wait for child thread t1 to complete execution.

   t2.start(); // thread t2 is ready to start.
   t2.join(); // wait for child thread t2 to complete execution.

   System.out.println("Main thread is ending");
 }
}
Output:
       Child thread1 starts running
       I: 1
       I: 2
       I: 3
       Child thread1 is ending
       Child thread2 starts running
       J: 1
       J: 2
       J: 3
       Child thread2 is ending
       Main thread is ending

Key Points to Remember

Here are some important points about the join() method in Java that you should keep in mind:

  • The purpose of the join() method is to pause the execution of the current thread until the thread on which join() has been called completes its execution.
  • This method helps synchronize threads, ensuring that one thread finishes before another starts or continues.
  • There are three versions of the join() method:
    • join()
    • join(long millis)
    • join(long millis, int nanos)
  • If the thread is interrupted while waiting to join, the join() method throws an exception named InterruptedException.
  • The join() method is commonly used when one thread depends on the result or completion of another thread’s work.

In this tutorial, we have covered all important points related to join() method in Java through example programs. We hope that you have understood the basic definition of join() method and practiced programs based on them.

Stay tuned with the next tutorial where you will understand thread synchronization in Java through real-time example. If you get any mistake in this tutorial, please inform us through email.
Thanks for reading!!!