Java Thread Join Example
In this article, I am going to show you an example ofThread.join. It can be used in a scenario where the calling thread has to rely on the results of execution of one or more sub-tasks and can’t proceed unless the threads executing these sub-tasks are done with their job.
In brief,Thread.join() provides you with wait & notification mechanism where the execution of the calling thread is suspended until the object called finishes its execution.
Before we start with the examples, let’s first go through the mechanics ofThread.join.
1. Thread.Join Flow
WhenThread.join is called, it suspends the execution of the calling thread until the target thread is alive. Once the target thread is done with its job and terminates, the caller thread will automatically wake up.
In the below diagram, the caller thread starts two threadst1 andt2, each thread is assigned one specific task. The caller thread then calls ont1.join so that it is blocked from further execution tillt1 finishes its job. Oncet1 is done with its execution and terminates, it wakes up the caller thread. Next, caller thread callst2.join to wait ont2 till it is done with its task. Oncet2 finishes, caller thread wakes up and continues in its execution.
Thread.join throwsInterruptedException, if any thread has interrupted the current thread so when we call it we must make sure it is caught and dealt appropriately.
2. Thread.join variations
There are couple of variations onjoin() method:
join (long milliseconds)join (long milliseconds, long nanos)
In the first version of thejoin() method, instead of waiting indefinitely for the thread called to terminate, the calling thread waits for the milliseconds specified as a parameter of the method.
The second version of thejoin() method is very similar to the first version, it receives the waiting period in number of milliseconds and the number of nanoseconds.
3. Example of Thread.join()
In this example, the main thread creates two threads and assigns each one a task. It then calls onjoin to wait for the thread’s completion. The first task calculates the average of numbers and the second task calculates the median. Once both tasks are done, the main thread prints the results.
ThreadJoinExample:
package com.javacodegeeks.threads;import java.util.Arrays;import java.util.Collections;import java.util.List;public class ThreadJoinExample {public static void main(String[] args) {Integer[] values = new Integer[] { 3, 1, 14, 3, 4, 5, 6, 7, 8, 9, 11,3, 2, 1 };Average avg = new Average(values);Median median = new Median(values);Thread t1 = new Thread(avg, "t1");Thread t2 = new Thread(median, "t2");System.out.println("Start the thread t1 to calculate average");t1.start();System.out.println("Start the thread t2 to calculate median");t2.start();try {System.out.println("Join on t1");t1.join();System.out.println("t1 has done with its job of calculating average");} catch (InterruptedException e) {System.out.println(t1.getName() + " interrupted");}try {System.out.println("Join on t2");t2.join();System.out.println("t2 has done with its job of calculating median");} catch (InterruptedException e) {System.out.println(t2.getName() + " interrupted");}System.out.println("Average: " + avg.getMean() + ", Median: "+ median.getMedian());}/** * Calculate average of numbers. Sum all the int values and divide it by * total count. */private static class Average implements Runnable {private Integer[] values;private int mean;Average(Integer[] values) {this.values = values;}@Overridepublic void run() {mean = 0;int n = values.length;for (int i : values) {mean += i;}mean /= n;}public int getMean() {return mean;}}/** * Sorts the given int list and calculates the median value. If size is * even, the mean of middle and middle-1. * */private static class Median implements Runnable {private Integer[] values;private int median;Median(Integer[] values) {this.values = values;}@Overridepublic void run() {List sortedList = Arrays.asList(values);Collections.sort(sortedList);int n = values.length;int middle = n / 2;if (n % 2 == 0) {median = (sortedList.get(middle) + sortedList.get(middle - 1)) / 2;} else {median = sortedList.get(middle);}}public int getMedian() {return median;}}}Output:
Start the thread t1 to calculate averageStart the thread t2 to calculate medianJoin on t1t1 has done with its job of calculating averageJoin on t2t2 has done with its job of calculating medianAverage: 5, Median: 4
4. Example of Thread.join(millis)
In this example, I will show the other variation ofThread.join which takes the waiting period as the parameter. The calling thread will wait only for the number of milliseconds passed in.
The main thread creates a thread and assigns it a sub task. Just to make sure sub task takes a while to complete, I have calledThread.sleep(100000) so that it is blocked for 100000 millis. Once the thread is started, the main thread calls ont.join(100) so that it can wake up after 100 millis irrespective of whether the called thread has done its job or not. After waking up, it checks whether the called thread is still alive. If it is, then it simply interrupts the thread to end its execution.
ThreadJoinMillisExample:
package com.javacodegeeks.threads;public class ThreadJoinMillisExample {public static void main(String[] args) {SubTask subTask = new SubTask();Thread t = new Thread(subTask);t.start();try {System.out.println("Join on subTask thread but only for 100 millis");t.join(100);System.out.println("Main thread came out of join");} catch (InterruptedException e) {System.out.println("Main thread Interrupted!");}if (t.isAlive()) {System.out.println("SubTask is still alive, interrupt it");t.interrupt();}}private static class SubTask implements Runnable {@Overridepublic void run() {try {Thread.sleep(100000);} catch (InterruptedException e) {System.out.println("Subtask Interrupted!");}}}}Output:
Join on subTask thread but only for 100 millisMain thread came out of joinSubTask is still alive, interrupt itSubtask Interrupted!
5. Example of InterruptedException
In this example, I will show you howThread.join can be interrupted by the thread on which the calling thread is waiting. The main thread creates a thread and assigns a sub task to it and then calls ont.join() to wait for the results. The sub task thread interrupts the main thread once it has the results the main thread is interested in. After interruption, the sub task continues further executing some more task. Meanwhile, the main thread wakes up due to interruption and obtains the result from sub task.
ThreadJoinInterruptionExample:
package com.javacodegeeks.threads;public class ThreadJoinInterruptionExample {public static void main(String[] args) {ThreadJoinInterruptionExample caller = new ThreadJoinInterruptionExample();caller.startSubTask();}public void startSubTask() {System.out.println("Start subtask");SubTask subTask = new SubTask(Thread.currentThread());Thread t = new Thread(subTask);t.start();try {t.join();} catch (InterruptedException e) {System.out.println("Interrupted, lets check the result");}System.out.println("Got the result? " + (subTask.getResult() != null));}private class SubTask implements Runnable {private Thread callerThread;private Object result;SubTask(Thread callerThread) {this.callerThread = callerThread;}@Overridepublic void run() {doTask();System.out.println("task done, interrupt the thread waiting on the result");callerThread.interrupt();doSomeMoreTask();}private void doTask() {System.out.println("do task");result = new Object();}private void doSomeMoreTask() {System.out.println("do some more task");}public Object getResult() {return result;}}}Output:
Start subtaskdo tasktask done, interrupt the thread waiting on the resultdo some more taskInterrupted, lets check the resultGot the result? true
Download the Eclipse Project
In this article, I have shown you Java Thread Join Examples.
You can download the source code here: threadjoin.zip

Thank you!
We will contact you soon.




