Wednesday, February 6, 2013

How to Join Multiple Threads in Java - Thread Join Example

Join method from Thread class is an important method and used to impose order on execution of multiple Threads. Concept of joining multiple threads is very popular on  mutithreading interview question. Here is one of such question, “You have three threads T1, T2 and T3, How do you ensure that they finish in order T1, T2, T3 ?. This question illustrate power of join method on multithreaded programming. Unlike classical thread questions like difference between wait and sleep method or solving producer consumer problem in Java, This one is bit tricky. You can do this by using join method, by calling T1.join() from T2 and T2.join() from T3. In this case thread T1 will finish first, followed by T2 and T3. In this Java multithreading tutorial we will have a closer look on join method with a simple example. Idea is to illustrate how join method works in simple words. By the way from Java 5 onwards you can also use CountDownLatch and CyclicBarrier classes to implement scenarios like one thread is waiting for other threads to finish there task.


When to use join method in Java

When to use Thread Join method with ExampleAs I said join is an important and useful method from Thread class but many times overlooked. Similar to wait method, by using join method, we can make one Thread to wait for another. Primary use of Thread.join() is to wait for another thread and start execution once that Thread has completed execution or died. Join is also a blocking method, which blocks until thread on which join has called die or specified waiting time is over. By the way understanding, how join method works, is not straight forward. Many developers get confused on things like, which thread will wait,  which thread will join etc. These points will be more clear when we go through an example of joining multiple Thread in Java using join() method.

Thread Join Example  in Java

Here is a simple example of joining two threads using Thread.join() method. By the way unlike Thread.sleep() method, join() is not a static method, it needs to be call on a java.lang.Thread object. Current thread, which calls join method will wait until thread on which join has called die or wait at most specified millisecond for this thread to die.

/**
 * Sample Java class to illustrate How to join two threads in Java.
 * join() method allows you to serialize processing of two threads.
 */

public class Join {
 
    public static void main(String args[]) throws InterruptedException{
     
        System.out.println(Thread.currentThread().getName() + " is Started");
     
        Thread exampleThread = new Thread(){
            public void run(){
                try {
                    System.out.println(Thread.currentThread().getName() + " is Started");
                    Thread.sleep(2000);
                    System.out.println(Thread.currentThread().getName() + " is Completed");
                } catch (InterruptedException ex) {
                    Logger.getLogger(Join.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        };
     
        exampleThread.start();
        exampleThread.join();
     
        System.out.println(Thread.currentThread().getName() + " is Completed");
    }
 
}

Output:
main is Started
Thread-0 is Started
Thread-0 is Completed
main is Completed

If you look at above example, first main thread is started and than it creates another thread, whose name is "Thread-0" and started it. Since Thread-0 sleep for 2 seconds, it require at least 2 seconds to complete and in between main thread called join method on Thread-0 object. Because of join method, now main thread will wait until Thread-0 completes its operation or You can say main thread will join Thread-0. If you look on output, it confirms this theory.

Important point on Thread.join method
Now we know How to use join method in Java, it’s time to see some important points about Thread.join() method.

1. Join is a final method in java.lang.Thread class and you cannot override it.
2) Join method throw IntrupptedException if another thread interrupted waiting thread as a result of join() call.

3) Join is also an overloaded method in Java, three version of join() available, check javadoc for details.

That’s all on How to join two Threads in Java with example. You can Join multiple threads by using Thread.join() method. Join is particularly useful to make one thread wait for other, or serializing two function e.g. first load your cache and than start processing request.

Related Java multithreading Tutorials from Javarevisited Blog

10 comments :

chiranjib swain said...

Nice article on join() method .If you provide more article or information with example on CountDown & Cyclic barrier classes then it would be very useful to us. Thanks

Javin @ ClassLoader in Java said...

@Chiranjib, Thanks for liking this comment. By the way I do have couple of post on CountDownLatch and CyclicBarrier, You can check this http://javarevisited.blogspot.com/2012/07/countdownlatch-example-in-java.html and Ofcourse I will be keep sharing on this topic.

Anonymous said...

Given Q: “You have three threads T1, T2 and T3, How do you ensure that they finish in order T1, T2, T3 ?.

Given A: You can do this by using join method by calling T3.join() from T2 and T2.join() from T1.

Comment : In this case, won't the finishing order be T3, T2 and T1 rather T1, T2 and T3.

Javin @ ClassLoader in Java said...

@Anonymous, You are absolutely correct. If we join in that sequence order would be T3, T2 and T1.

Correct answer should be T3.T2.T1 means T2.join() from T3 and T1.join() from T2. In this case T1 will finish first followed by T2 and T3.

Anonymous said...

That's a good question to ask. Can you share some use cases where join can be used ?

SARAL SAXENA said...

@Anonymous & Javin.. Please find the below code to achieve this...

package saxbean;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class ThreadOrdering {

static int NUM_THREADS = 3;

public static void main(String[] args) {
ExecutorService exec = Executors.newFixedThreadPool(NUM_THREADS);
class MyCallable implements Callable {
private final int threadnumber;

MyCallable(int threadnumber){
this.threadnumber = threadnumber;
}

public Integer call() {
System.out.println("Running thread #" + threadnumber);
return threadnumber;
}
}

List> callables =
new ArrayList>();
for(int i=1; i<=NUM_THREADS; i++) {
callables.add(new MyCallable(i));
}
try {
List> results =
exec.invokeAll(callables);
for(Future result: results) {
System.out.println("Got result of thread #" + result.get());
}
} catch (InterruptedException ex) {
ex.printStackTrace();
} catch (ExecutionException ex) {
ex.printStackTrace();
} finally {
exec.shutdownNow();
}
}
}

And finally the result that you will obtain..
Running thread #1
Running thread #3
Running thread #2
Got result of thread #1
Got result of thread #2
Got result of thread #3


At last I hope you guys want to achieve this same thing.

SARAL SAXENA said...

Create 3 threads but dont start them, then go as follows
t1.start();
t1.join();
t2.start();
t2.join();
t3.start();
Thread.join waits for a thread to terminate, so the order is guaranteed

Anonymous said...

I was reading this article and i fount it very useful. I have this task:
To start service D, service A and B need to be started
To stop service A, service B, D and C must be stopped first
Service B and C can be started in parallel immediately after A has started. Conversely, they can stop in parallel.

Do you have nay suggestions how can i solve it? I'm new in java so i don't know so much things but any advice, suggestions would be useful.

Julie and Jitu said...

good one by SARAL SAXENA ... thanks a lot

Anonymous said...

@ SARAL SAXENA

I have doubt on your code, re rewitten below
suppose we execute below code from main method

#1. t1.start();
#2. t1.join();
#3. t2.start();
#4. t2.join();
#5. t3.start();
#6. t3.join();

at #1 t1 started by main thread
at #2 main thread joined after t1, means main thread will wait for t1 to complete
at #3 t2 started by main thread
at #4 main thread joined after t2, means main thread will wait for t2 to complete

so up to line 4 main thread is waiting for both t1 and t2 to finish their execution
but
It doesn't mean that t2 waiting for t1 to complete, and same thing for line 5 and 6

at the end of line 6 main thread is waiting for t1, t2 and t3

So my question is how we can guaranty that t2 will execute after t1 and t3 will execute after t2 , because no where we its written like t3.join() from t2 and t2.join() from t1 ?

Post a Comment