Java Thread join() Method Example

Java Thread Examples


This post describes the usage of the Java Thread join() method with an example.

Java Thread join() Method Overview

The Thread join() method waits for a thread to die. In other words, it causes the currently running threads to stop executing until the thread it joins with completes its task.

Java Thread join() Method Example

Let's first create a Task that will calculate the sum of 1-5 numbers(maintained in for-loop). In the main thread lets create 4 tasks:
final Task task1 = new Task(500l);
final Task task2 = new Task(1000l);
final Task task3 = new Task(2000l);
final Task task4 = new Task(50l);
Now, let's create 4 threads to run above 4 tasks:
final Thread thread1 = new Thread(task1); 
final Thread thread2 = new Thread(task2);
final Thread thread3 = new Thread(task3);
final Thread thread4 = new Thread(task4);
Assign a name to each and start all the 4 threads:
thread1.setName("thread-1");
thread2.setName("thread-2");
thread3.setName("thread-3");
thread4.setName("thread-4");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
In this example, when the target thread finishes the sum, the caller thread (main) wakes up and calls the task.getSum() method which will certainly contain the total sum as the target thread has already finished its job.
The task4 has a small sleep time and therefore it finishes the sum before the others. Hence, the main thread calls the thread4.join() but immediately returns to its execution as the thread4 is finished.
/**
 * This class demonstrate the how join method works with an example. 
 * @author Ramesh Fadatare
 *
 */
public class ThreadJoinExample {
    public static void main(final String[] args) throws InterruptedException {
        System.out.println("Thread main started");
  
       final Task task1 = new Task(500l);
       final Task task2 = new Task(1000l);
       final Task task3 = new Task(2000l);
       final Task task4 = new Task(50l);
       final Thread thread1 = new Thread(task1); 
       final Thread thread2 = new Thread(task2);
       final Thread thread3 = new Thread(task3);
       final Thread thread4 = new Thread(task4); 
       thread1.setName("thread-1");
       thread2.setName("thread-2");
       thread3.setName("thread-3");
       thread4.setName("thread-4");
       thread1.start();
       thread2.start();
       thread3.start();
       thread4.start();
  
       System.out.println("[" + Thread.currentThread().getName() + "] waiting for " + thread1.getName());
       thread1.join();
       System.out.println(thread1.getName() + " finished! Result: " + task1.getSum());
  
       System.out.println("[" + Thread.currentThread().getName() + "] waiting for " + thread2.getName());
       thread2.join();
       System.out.println(thread2.getName() + " finished! Result: " + task2.getSum());
  
      System.out.println("[" + Thread.currentThread().getName() + "] waiting for " + thread3.getName());
      thread3.join();
      System.out.println(thread3.getName() + " finished! Result: " + task3.getSum());
  
     // As thread-4 already finished (smaller sleep time), the join call only immediately
     // returns the control to the caller thread
     System.out.println("[" + Thread.currentThread().getName() + "] waiting for " + thread4.getName());
     thread4.join();
     System.out.println(thread4.getName() + " finished! Result: " + task4.getSum());
  
     System.out.println("Thread main finished");
   }
}

class Task implements Runnable {
     private long sleep; 
     private int sum;
 
     public Task(final long sleep) {
         this.sleep = sleep;
     }
 
     @Override
     public void run() {
         for (int i = 1; i <= 5; i++) {
              System.out.println("[" + Thread.currentThread().getName() + "] Adding " + i);
              sum += i;
              try {
                  Thread.sleep(sleep);
              } catch (final InterruptedException e) {
                  e.printStackTrace();
              }
         }
     }
 
     public int getSum() {
         return this.sum;
     }
}
Output:
Thread main started
[thread-1] Adding 1
[thread-2] Adding 1
[thread-3] Adding 1
[main] waiting for thread-1
[thread-4] Adding 1
[thread-4] Adding 2
[thread-4] Adding 3
[thread-4] Adding 4
[thread-4] Adding 5
[thread-1] Adding 2
[thread-1] Adding 3
[thread-2] Adding 2
[thread-1] Adding 4
[thread-1] Adding 5
[thread-3] Adding 2
[thread-2] Adding 3
thread-1 finished! Result: 15
[main] waiting for thread-2
[thread-2] Adding 4
[thread-2] Adding 5
[thread-3] Adding 3
thread-2 finished! Result: 15
[main] waiting for thread-3
[thread-3] Adding 4
[thread-3] Adding 5
thread-3 finished! Result: 15
[main] waiting for thread-4
thread-4 finished! Result: 15
Thread main finished
Note that the output, main() thread finished it's executions last. Try to understand the example via looking into an output.
join() method throws an InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.

Reference

Comments