How to execute Java Threads in the same Order they were started using join() Method

In this tutorial we will discuss about the join() method from Thread class. This method is important method from Thread class and it imposes order on execution of the threads. Therefore join() method ensures that multiple threads run in sequence, i.e., in the same order the threads were started.

Let’s say threads t1, t2, t3 started execution in order and you need to ensure that t2 does not start until t1 finishes its execution, similarly t3 does not start until t2 finishes its execution. In this case we can write t1.join(), t2.join() and t3.join() to execute the t1, t2, t3 in order.

As we know that threads finish execution in random order, so join() method comes to rescue. join() method is used when you want to wait for the thread to finish. The signature of join() method is given below:

public final void join() throws InterruptedException

If join() method is called on any thread, then it will wait until the thread on which it is called gets terminated. So by using join() method we can make one thread wait for another thread.

join() is also a blocking method, which blocks until the thread on which join() method called dies or specified waiting time is over.

We sometimes become confused on things like, which thread will wait and which thread will join. Probably these points will be clear when we go through an example of joining multiple threads using join() method.

As we have seen the signature of join() method above, so it is clear that it is not a static method. So we have to call this method on thread object. The current thread which calls the join() will wait until the thread on which join called dies or waits at most the specified time for this thread to die.

join() is a final method from Thread class so we cannot override it.

Let’s create an example to check how join() method works. First we will check the execution order of threads without join() method and then we will use join() method to maintain execution order of threads they were started.

Without join()

public class ThreadJoinExecutionOrder {

	public static void main(String[] args) throws InterruptedException {
		Runnable r = () -> {
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("Thread [" + Thread.currentThread().getName() + "] executing");
		};

		Thread t1 = new Thread(r, "Thread 1");
		Thread t2 = new Thread(r, "Thread 2");
		Thread t3 = new Thread(r, "Thread 3");
		Thread t4 = new Thread(r, "Thread 4");

		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}

}

Running the above class will give you following output.

Thread [Thread 4] executing
Thread [Thread 2] executing
Thread [Thread 1] executing
Thread [Thread 3] executing

So it is clear from the above output that threads finished their execution randomly and we do not have any control on it and it depends on thread scheduler of the Java program.

With join()

public class ThreadJoinExecutionOrder {

	public static void main(String[] args) throws InterruptedException {
		Runnable r = () -> {
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("Thread [" + Thread.currentThread().getName() + "] executing");
		};

		Thread t1 = new Thread(r, "Thread 1");
		Thread t2 = new Thread(r, "Thread 2");
		Thread t3 = new Thread(r, "Thread 3");
		Thread t4 = new Thread(r, "Thread 4");

		t1.start();
		t1.join();

		t2.start();
		t2.join();

		t3.start();
		t3.join();

		t4.start();
		t4.join();
	}

}

Running the above class will give you the following output:

Thread [Thread 1] executing
Thread [Thread 2] executing
Thread [Thread 3] executing
Thread [Thread 4] executing

Now we have got our threads finished execution in the same order they were started.

Source Code

Download

Thanks for reading.

Related posts

Leave a Comment