What is the Thread.join() method in Java?

Overview

Thread.join() is a method in Java that causes the current thread to pause execution until the specified thread terminates. This is useful when we want to wait for a specific thread to complete before continuing the execution of the current thread.

For example, let's suppose we have a main thread and two child threads. The main thread creates the child threads. Then, it calls Thread.join() on each child thread and waits for them to complete before continuing execution. This ensures that the main thread does not continue until both child threads have finished.

The Thread.join() method can be called on any thread. However, if it is called on the current thread, it will simply wait forever—because the current thread can never terminate. Therefore, it is important when using Thread.join() to make sure that the thread we are waiting for will actually terminate.

Syntax

There are three overloaded versions of the Thread.join() method:

public final void join() throws InterruptedException

This makes the calling thread wait forever for the specified thread to terminate.

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

This makes the calling thread wait for the specified thread to terminate, or the specified amount of time to elapse (whichever comes first).

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

This does the same as the second version, but also allows us to specify a nanosecond timeout in addition to the millisecond timeout.

Type and Parameters

The Thread.join() is a void method so it doesn't return anything and has the following two parameters:

  • millis: This represents the number of milliseconds to wait for.
  • nanos: This represents the number of nanoseconds to wait for.

Thread.join() throws InterruptedException. The current thread’s interrupted status is cleared when this exception is thrown.

Example

In the following example, we create a main thread and two child threads. The main thread creates the child threads and then calls Thread.join() on each of them, waiting for them to complete before continuing execution. This ensures that the main thread does not continue until both child threads have finished.

class Test {
public static void main(String args[]) {
Thread t1 = new Thread(new Runnable() {
public void run() {
// The task to be executed by child thread 1
System.out.println("Inside t1");
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
// The task to be executed by child thread 2
System.out.println("Inside t2");
}
});
// Starting the child threads
t1.start();
t2.start();
// Waiting for child threads to finish
try {
t1.join();
t2.join();
System.out.println("t1 & t2 finished");
} catch (InterruptedException e) {
// Handling the exception
System.out.println("Interrupted Exception");
}
// Continuing the execution of the main thread \
}
}

Explanation

  • Lines 2-15: In this code, there are three threads. One is the main thread, and the other two are child threads t1 and t2. The main thread creates the child threads and then waits for them to finish before continuing. This makes sure that the main thread doesn't continue until both child threads have finished.
  • Lines 23-24: You can also see how to use t1.join() and t2.join() which makes the main thread wait for a specific time for the child threads to finish. Note that if you try to join a thread that has already finished, the join() method will return immediately.
  • Lines 26-29: It is also important to note that the join() method can throw an InterruptedException. This exception occurs when another thread interrupts the current thread while waiting for the specified thread to finish. When this happens, the current thread’s interrupted status is cleared, and the join() method throws an InterruptedException.
  • Line 22-29: shows how to handle an InterruptedException when using Thread.join(). In this code, the try-catch block is used to handle the InterruptedException. If an InterruptedException occurs, the code in the catch block is executed. This could be used to log the exception or perform some other type of error handling.

The Thread.join() method is a blocking call. This means that it will cause the thread that calls it to stop executing until the thread it is waiting for has finished. Therefore, you should be careful when using Thread.join() in your code, as it can impact performance.

Conclusion

In this Answer, we looked at the Thread.join() method in Java. We saw how it could be used to make one thread wait for another to finish before continuing execution. We also saw how to handle the InterruptedException exception that can be thrown by the join() method. Finally, we discussed the performance implications of using Thread.join().

Free Resources