Joining Threads in Java

Last Updated : 17 Mar, 2026

In Java, threads allow concurrent execution of multiple tasks, improving performance and responsiveness. Sometimes, one thread needs to wait for another thread to finish its execution. java.lang. Thread class provides the join() method which allows one thread to wait until another thread completes its execution.

  • Used to achieved using the join() method of the Thread class.
  • When multiple threads use join(), its overloaded versions allow specifying a waiting time

join() Method

The join() method is used to pause the execution of the current thread until the thread on which it is called completes.

  • The current thread goes into a waiting state
  • It waits until the target thread finishes execution
  • Execution resumes after the thread is terminated
  • Helps in maintaining proper sequence between threads

Syntax:

public final void join()

Overloaded Versions of join() Method

1. join()

The join() method is used to make the current thread wait until the target thread completely finishes its execution. Waits until the thread completely finishes

Syntax:

public final void join()

2. join(long millis)

It will put the current thread on wait until the thread on which it is called is dead or wait for the specified time (milliseconds).Waits for a specified time or until the thread finishes

Syntax:

public final synchronized void join(long millis)

3. join(long millis, int nanos)

It will put the current thread on wait until the thread on which it is called is dead or wait for the specified time (milliseconds + nanos). Waits for a specified time (milliseconds + nanoseconds) or until completion

Syntax:

public final synchronized void join(long millis, int nanos)

Example: Java program to explain the concept of joining a thread.

Java
import java.io.*;

// Creating thread by creating the
// objects of that class
class ThreadJoining extends Thread
{
    @Override
    public void run()
    {
        for (int i = 0; i < 2; i++)
        {
            try
            {
                Thread.sleep(500);
                System.out.println("Current Thread: "
                        + Thread.currentThread().getName());
            }

            catch(Exception ex)
            {
                System.out.println("Exception has" +
                                " been caught" + ex);
            }
            System.out.println(i);
        }
    }
}

class GFG
{
    public static void main (String[] args)
    {

        // creating two threads
        ThreadJoining t1 = new ThreadJoining();
        ThreadJoining t2 = new ThreadJoining();
        ThreadJoining t3 = new ThreadJoining();

        // thread t1 starts
        t1.start();

        // starts second thread after when
        // first thread t1 has died.
        try
        {
            System.out.println("Current Thread: "
                  + Thread.currentThread().getName());
            t1.join();
        }

        catch(Exception ex)
        {
            System.out.println("Exception has " +
                                "been caught" + ex);
        }

        // t2 starts
        t2.start();

        // starts t3 after when thread t2 has died.
        try
        {
            System.out.println("Current Thread: "
                 + Thread.currentThread().getName());
            t2.join();
        }

        catch(Exception ex)
        {
            System.out.println("Exception has been" +
                                    " caught" + ex);
        }
        
        // t3 starts
        t3.start();
        
        // After t2 has dead, t3 starts
        try
        {
            System.out.println("Current Thread: "
                 + Thread.currentThread().getName());
            t3.join();
        }

        catch(Exception ex)
        {
            System.out.println("Exception has been" +
                                    " caught" + ex);
        }
    }
}

// This code is modified by Susobhan Akhuli

Output:

Current Thread: main
Current Thread: Thread-0
0
Current Thread: Thread-0
1
Current Thread: main
Current Thread: Thread-1
0
Current Thread: Thread-1
1
Current Thread: main
Current Thread: Thread-2
0
Current Thread: Thread-2
1

In the above example we can see clearly second thread t2 starts after first thread t1 has died and t3 will start its execution after second thread t2 has died.


Comment