Java Thread Join Example | Join Method in Java

Java Thread Join | 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 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 is as follows:

ThreadName.join(); // ThreadName is 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. The general form of join() method is:

final void join() throws InterruptedException

Two other overloaded versions of join() method of Thread class takes timeout arguments. The general forms of overloaded version of join() method 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 source code for better understand.

Program source code 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 program, join() method is called inside the main thread through Thread t. Hence, the main thread (current thread) is going to wait until thread t completes its execution and is terminated.


Program source code 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.

Program source code 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

Hope that this tutorial has covered all important points related to join() method in Java with example programs.
Thanks for reading!!!
Next ⇒ Thread Synchronization in Java⇐ PrevNext ⇒