When to use Thread.join() in Java Multithreading ?

The Thread.join() method in Java is used to ensure that the calling thread waits for the thread on which join() is called to finish its execution. This is especially useful when one thread (like the main thread) needs to wait for other threads to complete before proceeding with its own execution.

Key Points:

  1. Purpose:
    The purpose of join() is to synchronize one thread with the completion of another. When you call join() on a thread, the calling thread will be blocked until the target thread finishes execution.
  2. Thread coordination:
    join() helps in coordinating the execution of multiple threads, ensuring that certain threads finish before others start.
  3. Common Use Case:
    It is commonly used when you want the main thread (or any other thread) to wait for one or more threads to finish before continuing, for example, to ensure that some computation or task is fully completed.

Syntax:

  • void join(): Waits indefinitely for the thread to die.
  • void join(long millis): Waits at most the specified milliseconds for the thread to die.
  • void join(long millis, int nanos): Waits at most the specified milliseconds plus nanoseconds for the thread to die.

Example:

In this example, we will use join() to ensure the main thread waits for other threads to complete before continuing.

class MyThread extends Thread {
    public void run() {
        for (int i = 1; i <= 3; i++) {
            System.out.println(Thread.currentThread().getName() + " is running");
            try {
                Thread.sleep(1000);  // Simulate work
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class Main {
    public static void main(String[] args) {
        MyThread thread1 = new MyThread();
        MyThread thread2 = new MyThread();

        thread1.start();
        thread2.start();

        try {
            // Main thread waits for thread1 and thread2 to finish
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Both threads have finished. Main thread resumes.");
    }
}

Output:

Thread-0 is running
Thread-1 is running
Thread-0 is running
Thread-1 is running
Thread-0 is running
Thread-1 is running
Both threads have finished. Main thread resumes.

How join() works:

  1. The main thread starts thread1 and thread2.
  2. When join() is called on thread1 and thread2, the main thread waits for both threads to finish.
  3. Only after both threads complete their execution, the main thread continues and prints the final message.

Variants of join():

  1. join(long millis):
    You can specify a timeout. The calling thread waits up to a given time for the other thread to complete, but if the time expires, it stops waiting.
   thread1.join(2000);  // Waits for 2 seconds, then continues even if thread1 is still running
  1. join(long millis, int nanos):
    This method allows you to specify the waiting time in milliseconds and nanoseconds.
   thread1.join(1000, 500);  // Waits for 1 second and 500 nanoseconds

When to Use Thread.join():

  • Waiting for child threads: When the main thread needs to wait for other threads (child threads) to complete before proceeding. For example, when you’re working on concurrent tasks and need to wait for all tasks to be completed before merging results.
  • Thread termination: Ensuring that important threads complete execution before your program terminates.

Summary:

  • Thread.join() makes one thread wait for the completion of another thread.
  • This helps in managing and coordinating thread execution, ensuring that threads complete before proceeding to the next task.
  • Variants of join() allow waiting with a timeout for flexible control over thread synchronization.

Related Posts

Leave a Reply

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