How to join two threads in Java? Thread.join() example

You can join two threads in Java by using join() method from java.lang.Thread class. Why do you join threads? because you want one thread to wait for another before starts processing. It's like a relay race where the second runner waits until the first runner comes and hand over the flag to him. Remember, unlike sleep(), join() is not a static method so you need an object of java.lang.Thread class to call this method. Now, who calls and who wants and which thread dies? for example, if you have two threads in your program main thread and T1 which you have created. Now if your main thread executes this line T1.join() (main thread execute whatever you have written in the main method) then main thread will wait for T1 thread to finish its execution. The immediate effect of this call would be that main thread will stop processing immediately and will not start until T1 thread has finished. So, what will happen if T1 is not yet started and there is no one to start T1 thread? Well,  then you have a deadlock but if it's already finished then main thread will start again, provided it get the CPU back.

In this tutorial, you will learn how to make three threads execute in a order by using join() method. You an also check out Java Threads By Scott Oaks and Henry Wong to get a good starting overview of several fundamentals of threads and multi-threading.

Thread.join() Example in Java

In this program, I have tried to explain how to use join() method by solving a popular multi-threading interview question, how to execute three threads in a order, such that T1 will start first and finished last. In this example, I have create a class called ParallelTask which implements Runnable interface and used to create multiple threads.

In the run() method it first print message that it has started and then just calls join() method to wait for its predecessor thread to die before starting again, after that it prints finished execution. I have make these arrangement so that all thread finish their execution in order T3, T2 and T1.

AfterI create object of Thread T1, I set its predecessor as T2. Similarly I set T3 as predecessor of T2. Since its not guaranteed that when a thread will start after calling start() method, you may see that T3 starts before T2, even if we have called T2.start() prior to T3.start(), but by putting those join() statements, we have guaranteed their execution. There is no way that T2 will finish before T3 and T1 will finish before T2.

You can also check out Core Java Volume 1 - Fundamentals by Cay S. Horstmann to get a good starting overview of several fundamentals of threads and multi-threading.

How to join two thread in Java

Now, let me explain you execution of this program. Our program starts by JVM invoking main method() and the thread which executes main method is called main thread. How do you I know that? do you remember those "Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException" exceptions? You can see that Java prints name of thread as "main".

In our main() method we have first create three object of ParallelTask class which is nothing but Runnable. These task will be executed by three threads we will create next. We have given all thread meaningful name to understand output better, its actually best practice to name your threads.

Next, I have set predecessor for each thread, its nothing but another thread object and our ParallelTask has variable predecessor to hold reference of thread to which this thread will join. This is critical to ensure ordering between multiple thread.

Since each thread calls predecessor.join() method, by setting right predecessors you can impose ordering. In our example, threads will start in any order but will do processing such that T3 will finish first, followed by T2 and last by T1.

import java.util.concurrent.TimeUnit;

 * Simple Java Program to show how to execute threads in a particular order. You
 * can enforce ordering or execution sequence using Thread.join() method in
 * Java.
 * @author Javin Paul
public class JoinDemo {

    private static class ParallelTask implements Runnable {
        private Thread predecessor;

        public void run() {
            System.out.println(Thread.currentThread().getName() + " Started");

            if (predecessor != null) {
                try {
                } catch (InterruptedException e) {

            System.out.println(Thread.currentThread().getName() + " Finished");

        public void setPredecessor(Thread t) {
            this.predecessor = t;


    public static void main(String[] args) {

        // we have three threads and we need to run in the
        // order T1, T2 and T3 i.e. T1 should start first
        // and T3 should start last.
        // You can enforce this ordering using join() method
        // but join method must be called from run() method
        // because the thread which will execute run() method
        // will wait for thread on which join is called.

        ParallelTask task1 = new ParallelTask();
        ParallelTask task2 = new ParallelTask();
        ParallelTask task3 = new ParallelTask();

        final Thread t1 = new Thread(task1, "Thread - 1");
        final Thread t2 = new Thread(task2, "Thread - 2");
        final Thread t3 = new Thread(task3, "Thread - 3");


        // now, let's start all three threads


Thread - 1 Started
Thread - 1 Finished
Thread - 2 Started
Thread - 3 Started
Thread - 2 Finished
Thread - 3 Finished

From the output, you can see that threads have started in different order then the order their start() method has called, this is fine because you don't know which thread will get CPU. It all depends upon mood of thread scheduler, but you can see that threads are finished in correct order. Thread 3 finished first, Thread 2 second and Thread 1 last, the order we wanted. This is achieved by using join() method of java.lang.Thread class. It's very useful method to learn.

Some important points about join method in Java :

Thread.join() example in Java

That's all about how to join two thread in Java using Thread.join() method. You can use this to impose ordering between multiple thread e.g. suppose you want to start processing when all your caches are loaded. Though there are some concurrency utilities like CylicBarrier and CountDownLatch exists, knowing how it works at join level is very good for any Java developer. Let me know if you have doubt or question about Thread.join() method in Java.

Further Learning
Multithreading and Parallel Computing in Java
Applying Concurrency and Multi-threading to Common Java Patterns
Java Concurrency in Practice - The Book
Java Concurrency in Practice Bundle by Heinz Kabutz

Other Java Multithreading tutorials for curious developers :
  • What is difference between transient and volatile variable in Java? [answer]
  • How to stop a thread in Java? [solution]
  • How to pause a thread in Java? [example]
  • What is difference between a thread and a process? [answer]
  • How to use CyclicBarrier class in Java? [example]
  • What is difference between implements Runnable and extends Thread in Java? [answer]
  • 10 things you should know about Thread in Java? [article]
  • Difference between CountDownLatch and CyclicBarrier in Java? [answer]
  • When to use wait() and sleep() method in Java? [answer]
  • How to use CountDownLatch in Java? [example]
  • Difference between Callable and Runnable interface in Java? [answer]


  1. // we have three threads and we need to run in the
    // order T1, T2 and T3 i.e. T1 should start first
    // and T3 should start last.
    //The code should be like this then

    //Then the output will look like below. See how Thread 1 started and then Thread 2 and then Thread 3.
    Thread-1 started
    Thread-2 started
    Thread-1 finished
    Thread-3 started
    Thread-2 finished
    Thread-3 finished

    1. @Anonymous, good spot :) that was typo which is well caught by you. If you notice output was also showing that clearly, corrected now.

  2. Javin, what you said & what your program output shows is contradictory. You said, T3 should finish 1st, T2 should finish 2nd, T1 should finish last. Pls see the program output. The finishing order is exactly reverse of what you want.