Java Thread join() Method Tutorial

In this section, we will learn what the Thread join() method is and how to use it in Java.

Java Thread join() Method Definition and Usage

The `join()` method is used to make a thread wait for other threads that called this method to finish their work.

(I know it seems a bit confusing at first, but if you read the example in the paragraph below, things will click into place real fast. )

For example, we know that a Java program at least has one thread that is known as the main thread. Now, imagine that we add one more thread to a program and called it `t1`. Here, if we want to make the main thread to wait for the work of the `t1` thread to finish first and then continue to do its work, we can create the statement `t1.join()` as one of the statements that the `main` thread should execute. Now, after running this statement, the `main` thread will wait until the work of the `t1` thread is completely done. After that, the main thread is allowed to continue running the rest of its instructions.

In short, calling the `join()` method is like asking a thread to wait for another thread until it is dead, then continue to do the rest of works that it supposed to do.

Note that the thread that we want to make it wait won’t call this method! Instead, it’s those threads that we want the current thread to wait for them; they are the ones that call the join() method.

Also note that a thread that is waiting for other threads to join will be blocked in the `waiting-set` of the target monitor if the waited thread is in a synchronized method/block. Hence, it will release any lock it acquired and other threads can take the lock of the same monitor if they want to.

Java Thread join() Method Syntax:

public final void join() throws InterruptedException

public final synchronized void join(long mls) throws InterruptedException

public final synchronized void join(long mls, int nanos) throws InterruptedException

The method has three versions:

  • In the first version, it causes the target thread to wait until the thread that the method is called with, finishes its work. No-matter how long it takes; the target thread will wait.
  • The second version of this method puts a limit on the amount of time that the target thread should wait. This means the target thread will wait for a specific time (in milliseconds), if the thread that the method is called with, joined (finished its work), then the target thread will continue to run the rest of its tasks. But, if the target thread waited for the specified amount of time and the called thread didn’t join by that time, then the target thread will continue to do the rest of its work.
  • The third version of this method is just like the second version, with the exception that we can add a second argument that provides more precision to the amount of time we want a thread to wait. Note that the second argument is in nanosecond.

Notes:

  • We should call the join() method on a thread that is started! If we call the method on a thread that is not started yet, it will return immediately! Also, if we call the join() method on a thread that is dead, again, the method returns immediately.
  • We can call a thread to wait for itself using the join() method, but we shouldn’t! This is because like saying a thread must wait until itself is terminated! This will result in infinite waiting!

Java Thread join() Method Returns:

The join() method and its other versions don’t return a value.

Java Thread join() Method Exceptions:

The join() method might throw one exception and that is `InterruptedException`. We get this exception if any other thread interrupted the current thread.

Example: using Thread join() method in Java

public class Main {
    public int count = 0;
    public static void main(String[] args) {
        Main main = new Main();
        Runnable runnable = ()->{
            try {
                System.out.println("The second thread started...");
                Thread.sleep(3000);
                System.out.println("The second thread is done...");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };

        Thread thread = new Thread(runnable, "Second-Thread");
        thread.start();

        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("The work of the main thread is also done... ");

    }

}

Output:

The second thread started...

The second thread is done...

The work of the main thread is also done...

Leave a Reply