Java Thread Join Example

Filed Under: Java

Java Thread join method can be used to pause the current thread execution until unless the specified thread is dead. There are three overloaded join functions.

Java Thread join

java thread join, thread join example, java thread join example, thread join

public final void join(): This java thread join method puts the current thread on wait until the thread on which it’s called is dead. If the thread is interrupted, it throws InterruptedException.

public final synchronized void join(long millis): This java thread join method is used to wait for the thread on which it’s called to be dead or wait for specified milliseconds. Since thread execution depends on OS implementation, it doesn’t guarantee that the current thread will wait only for given time.

public final synchronized void join(long millis, int nanos): This java thread join method is used to wait for thread to die for given milliseconds plus nanoseconds.

Here is a simple example showing usage of Thread join methods. The goal of the program is to make sure main is the last thread to finish and third thread starts only when first one is dead.


package com.journaldev.threads;

public class ThreadJoinExample {

    public static void main(String[] args) {
        Thread t1 = new Thread(new MyRunnable(), "t1");
        Thread t2 = new Thread(new MyRunnable(), "t2");
        Thread t3 = new Thread(new MyRunnable(), "t3");
        
        t1.start();
        
        //start second thread after waiting for 2 seconds or if it's dead
        try {
            t1.join(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        t2.start();
        
        //start third thread only when first thread is dead
        try {
            t1.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        t3.start();
        
        //let all threads finish execution before finishing main thread
        try {
            t1.join();
            t2.join();
            t3.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        System.out.println("All threads are dead, exiting main thread");
    }

}

class MyRunnable implements Runnable{

    @Override
    public void run() {
        System.out.println("Thread started:::"+Thread.currentThread().getName());
        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Thread ended:::"+Thread.currentThread().getName());
    }
    
}

Output of the above program is:


Thread started:::t1
Thread started:::t2
Thread ended:::t1
Thread started:::t3
Thread ended:::t2
Thread ended:::t3
All threads are dead, exiting main thread

That’s all for a quick roundup on java thread join example.

Comments

  1. asdqqwe says:

    Why does t2 start before t1 ends? and t3 start before t2 ends?

    1. wdz says:

      A join() method is the code that the thread calling the method executes after the run() method

    2. sridip says:

      Question: Why does t2 start before t1 ends?
      Ans: Because t1.join(2000) makes the main thread wait for at most 2000 milliseconds whether thread t1 is dead or not. Here t1 is still alive after 2000ms but the lock is released from it to the waiting main thread which starts t2 by calling t2.start().

      Question: Why does t3 start before t2 ends?
      Ans: t3.start() is only dependent on t1’s death through t1.join(). Hence, t3 can start if it finds t1 is already dead. t3 is in no way dependent on t2’s death, hence can start without worrying about it being dead or alive.

      Hope it clarifies your question.

      Cheers!
      – Sridip

  2. Anon says:

    t2.start();

    //start third thread only when first thread is dead
    try {
    t1.join();

    It should be t2.join() instead of t1.join()

    1. wei,jinshui says:

      why t2.join() instead of t1.join()?

  3. manish says:

    Hi, What i need to use for Join thread in ExceutorService?

    1. Basu D says:

      executor.shutdown();
      while (!executor.awaitTermination(24L, TimeUnit.HOURS)) {
      System.out.println(“waiting for termination”);
      }

  4. Siddharth says:

    I have one doubt, as we can see in the implementation of the join() method , it waits until thread isAlive() method returen true. Now the question is when wait() is called on instance of the thread , it would be disabled for thread scheduling, So if i am calling join() on any thread instance , would it ever get chance to execute the code in run method as it is waiting in a loop over isAlive() method.

  5. Eswar says:

    Hi,
    I have one question in this,
    if t1 thread execution fails with NullPointer Exception , I need to stop the main thread or we have to capture wich thread is failed. Could you please explains this.

    1. Vijay Kambala says:

      Surrond the NullPointer Exception prone code inside a try-catch block
      or surrond the t1.start() method in try-catch block.

  6. Kamal Thakur says:

    Best Example so Far. Thanks a lot to making join looks so easy.

  7. pradpalnis says:

    Great explanations.This is wat needed…

  8. kumkum says:

    U are fab pankaj.

  9. Gopinath says:

    Simple but informative article:) Keep up the good work bro:)
    If possible pls add more articles to collection framework internals.

  10. guru ghule says:

    I have doubt if we called join() without thread refference just like
    public void m1()throws Exception
    {
    join();
    }

    what happened

    1. Pankaj says:

      You will get compile time error as “The method join() is undefined for the type XXX”

      1. ram says:

        what if i call
        Thread.currentThread().join(); in main thread?

        1. Vijay Kambala says:

          Thread.currentThread().join();
          System.out.println(“bbbbbbbbbbbbbbbb”);

          if the above code is written inside main method
          “bbbbbbbbbbbbbbbb” is never printed in JVM’s life time

  11. GreatestJoy says:

    HI pankaj
    After going through ur code i was having certain doubts over the order of output you provided here so i ran the same code on my machine and the correct order of output is this :

    Thread started:::t1
    Thread started:::t2
    Thread ended:::t1
    Thread started:::t3
    Thread ended:::t2
    Thread ended:::t3
    All threads are dead, exiting main thread

    Thread t1 doesn’t end until thread t2 starts. I think that’s because while t1 goes to sleep for 4000 millisec main thread is still executing and as soon as it encounters t1.join(2000) it stops its own execution for the same time period but, thread t1 still has to wait for another 2000 millisec before completion. Meanwhile t2 starts and before t1 could complete its execution the line prints Thread started::::t2

    For 2000 millisec the t1 thread’s sleep execution and t1’s join execution run in parallel

    Tell me if the above explanation is wrong.

    1. Pankaj says:

      Yes you are right, I am not sure how I got that output. Must be some typo I guess, I have corrected the post. Thanks for catching!

  12. Balaji says:

    t1.join(2000); means.. does the t1 joins the main method ?

    1. Pankaj says:

      No main method is waiting for t1 thread to finish for 2 seconds. If time is passed, main method starts executing.

  13. George Chou says:

    I am curious why t3.join() can be called when t2.join() is already called.
    I mean doesn’t t2.join() block main thread?
    If that’s the case, why can the main thread proceed to execute t3.join()?

    1. Krishna says:

      T3.join() will get called when the T2 thread dies and Main will be blocked again till the t3 thread dies.

      1. Pankaj says:

        Thanks for the response Krishna.

  14. Ramakant says:

    t1.join() is not required for the main thread to be end as t3.start() already took care of t1 dead state.

    1. Pankaj says:

      Yes you are right, put some join method with time and check the output to learn more. The example code is to understand the join method.

  15. srini says:

    How Can make sure the order of execution of the threads?

    First t1 should execute,then t2 and then t2 using join method

    1. Pankaj says:

      call t1.join() before calling t2.start() and so on.

  16. Amishi Shah says:

    Hi Pankaj,

    Could you please explain the difference between t1,join(2000) and Thread.sleep(2000), in both the cases, the current thread waits for 2000 ms.

    Is there any difference in terms of locks or resources?

    Regards,
    Amishi

    1. Pankaj says:

      Both are completely different things, sleep() causes current thread to wait for given time. join() is used with wait for another thread to complete execution or wait for given time. For example, in above program main() thread is using join() to wait for other threads to finish.

  17. Mark says:

    Would you explain to me: when we use join() method in this example, we say to main method (but not some other thread) to wait until some thread died or some time passed ? – so every call join() we do from main method or we call it from the thread we recently started ?
    And on the line 32 “t1.join();” – if we comment that, it will not break anything ?

  18. LinTao says:

    There maybe a small mistake about the description of the 3 overloaded functions. They are all “public final void” method in Java doc: http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html. Any special thought add “synchronized” here?
    BTW, I found this post from another one given by you: Multi-Threading and Concurrency Interview Questions with Answers. It helped me a lot for understanding java thread. Thanks a lot!

    1. Pankaj says:

      The method syntax is correct, please check the Thread class source code.

      1. LinTao says:

        I’ve just check the Harmony code. FYI, the 3 methods are declared as this:
        public final synchronized void join() throws InterruptedException
        public final void join(long timeoutInMilliseconds) throws InterruptedException
        public final synchronized void join(long timeoutInMilliseconds, int nanos) throws InterruptedException

  19. Preetam says:

    Thread started : t1 time : Fri Jan 10 18:49:30 IST 2014
    Thread started : t2 time : Fri Jan 10 18:49:32 IST 2014
    Thread ended : t1 time : Fri Jan 10 18:49:34 IST 2014
    Thread started : t3 time : Fri Jan 10 18:49:34 IST 2014
    Thread ended : t2 time : Fri Jan 10 18:49:36 IST 2014
    Thread ended : t3 time : Fri Jan 10 18:49:38 IST 2014

    1. Preetam says:

      t1 waits only for 2 seconds before t2 starts

      1. Issac says:

        m1 m1 main end
        t1 t1 t1 t1
        t2 t2 t2 t2
        t3 t3 t3 t3
        Thread started:::t1 Thu May 07 11:00:09 CST 2015
        Thread started:::t2 Thu May 07 11:00:11 CST 2015
        Thread ended:::t1 Thu May 07 11:00:13 CST 2015
        Thread started:::t3 Thu May 07 11:00:13 CST 2015
        Thread ended:::t2 Thu May 07 11:00:15 CST 2015
        Thread ended:::t3 Thu May 07 11:00:17 CST 2015
        All threads are dead, exiting main thread

        1. RAGHU says:

          If we take a look at the recorded timings carefully for each thread t1, t2 and t3 there is a difference of 4 seconds between their start time and end time.

          This confirms that each thread took 4 seconds to complete/process the logic in their run method {as in-side it has Thread.sleep(4000)}

          All that matters here is that the main thread waits indefinitely if we just use join() and it will ensure to move to the next line only after the child thread dies {t1, t2 and t3}

          But if we use join(2000) the main thread waits for only 2 seconds and just moves to next line with-out bothering whether the child thread died or not.

          And due to the above reason, the t2 started even before the t1 dies

  20. swamy says:

    Hi

    I have one question like

    Why sleep and yield methods are static?

    1. Pankaj says:

      If you will look into the sleep() and yield() method details, they work on the current executing thread, so there is no point in calling these methods on some other threads that are not executing i.e in wait state. That’s why these methods are made static so that when this method is called statically, it works on the current executing thread and avoid confusion to the programmers who might think that they can invoke these methods on some non-running threads.

      It’s a very interesting question and that’s why it’s part of https://www.journaldev.com/1162/java-multi-threading-concurrency-interview-questions-with-answers

  21. Amitabha Roy says:

    Line 10: t1 starts
    Line 14: main thread waits till t1 ends
    Line 19: t1 ended, main thread starts t2
    Line 23: TYPO?? t2.join() will cause main thread to wait till t2 ends
    Line 28: t2 ended, main thread starts t3
    Line 32: no use of it
    Line 33: no use of it
    Line 34: main thread will wait till t3 ends

    1. peng li says:

      Good one

  22. Rajesh says:

    Here:

    //let all threads finish execution before finishing main thread
    try {
    t1.join();
    t2.join();
    t3.join();

    Do you really need to check if thread 1 as ended ? Isn’t T1 suppoed to end before T3 starts in code ? Maybe I am overlooking something.

    1. Pankaj says:

      It’s just an example code to understand the Thread join() method.

      Yes you are right, since t1.join() is already called, it’s dead so we can just call join methods on t2 and t3.

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages