purpose of join() method in Thread

join() method is defined in Thread class. join() method waits for a thread to die. That means, it causes the currently running threads to stop executing until the thread it joins with completes its task.


class NewThread1 implements Runnable{
	String name; //name of Thread
	Thread t;
	
	NewThread1(String threadname){
		name=threadname;
		t = new Thread(this,name);
		System.out.println("New thread:"+t);
		t.start();
	}
	
	public void run(){
		try
		{
		for(int i=5;i>0;i--)
		{
		System.out.println(name+":"+i);
		Thread.sleep(1000);
		}
		}
		catch(InterruptedException ie){
			System.out.println(name+" Interrupted");
		}
		
		System.out.println(name+" Exiting");
	}
	
	
}


public class JoinCheck {
	public static void main(String args[])
	{
	NewThread1 nt1=new NewThread1("One");
	NewThread1 nt2;
	NewThread1 nt3;
	NewThread1 nt4;
	//start the threads
	//nt1=new NewThread1("One");
	nt2=new NewThread1("Two");
	nt3=new NewThread1("Three");
	nt4=new NewThread1("Four");
	
	threads_status(nt1,nt2,nt3,nt4);
	try
	{
	nt1.t.join();
	nt2.t.join();
	nt3.t.join();
	nt4.t.join();

	
	
	System.out.println("completed all four threads");
	}catch(Exception ien)
	{
		System.out.println("main thread Interrupted");
	}
	
	threads_status(nt1,nt2,nt3,nt4);
	System.out.println("main thread Exiting");
	}

	private static void threads_status(NewThread1 nta,NewThread1 ntb,NewThread1 ntc,NewThread1 ntd)
	{
	System.out.println("Thread One Alive?"+nta.t.isAlive());
	System.out.println("Thread Two Alive?"+ntb.t.isAlive());
	System.out.println("Thread Three Alive?"+ntc.t.isAlive());
	System.out.println("Thread Four Alive?"+ntd.t.isAlive());
	}
	
}

In Thread, purpose of join() and isAlive() methods

As known below are the methods available in Thread class
setName()
getName()
setPriority()
getpriority()
sleep()
start()
join()
isAlive()

When to use join() method. Before we try to understand join(), lets see what is Daemon thread. A Daemon thread is a thread, which keeps on running in the background, even though its parent , has already completed execution, and no more exit. Daemon threads, can be avoided using join() method. Whenever join() is invoked, with a thread object(say t1). Execution of main threads waits, until thread t1 completes execution.

Also isAlive() method is provided, just to check if an invoking thread, is still alive, or has completed execution.
isAlive() returns true if invoking thread is still alive, else returns false.

Below is an example, showing, how main thread is kept alive until all child threads have completed execution.


class NewThread1 implements Runnable{
	String name; //name of Thread
	Thread t;
	
	NewThread1(String threadname){
		name=threadname;
		t = new Thread(this,name);
		System.out.println("New thread:"+t);
		t.start();
	}
	
	public void run(){
		try
		{
		for(int i=5;i>0;i--)
		{
		System.out.println(name+":"+i);
		Thread.sleep(1000);
		}
		}
		catch(InterruptedException ie){
		System.out.println(name+" Interrupted");
		}
		
		System.out.println(name+" Exiting");
	}
	
	
}


public class JoinCheck {
	public static void main(String args[])
	{
		NewThread1 nt1=new NewThread1("One");
		NewThread1 nt2;
		NewThread1 nt3;
		NewThread1 nt4;
		//start the threads
		//nt1=new NewThread1("One");
		nt2=new NewThread1("Two");
		nt3=new NewThread1("Three");
		nt4=new NewThread1("Four");
		
		threads_status(nt1,nt2,nt3,nt4);
	try
	{
		nt1.t.join();
		nt2.t.join();
		nt3.t.join();
		nt4.t.join();
		
		
	System.out.println("completed all four threads");
	}catch(Exception ien)
	{
	System.out.println("main thread Interrupted");
	}
	
	threads_status(nt1,nt2,nt3,nt4);
	System.out.println("main thread Exiting");
	}

	private static void threads_status(NewThread1 nta,NewThread1 ntb,NewThread1 ntc,NewThread1 ntd)
	{
	System.out.println("Thread One Alive?"+nta.t.isAlive());
	System.out.println("Thread Two Alive?"+ntb.t.isAlive());
	System.out.println("Thread Three Alive?"+ntc.t.isAlive());
	System.out.println("Thread Four Alive?"+ntd.t.isAlive());
	}
	
}

Output:
New thread:Thread[One,5,main]
New thread:Thread[Two,5,main]
New thread:Thread[Three,5,main]
Two:5
New thread:Thread[Four,5,main]
Thread One Alive?true
Thread Two Alive?true
Thread Three Alive?true
Thread Four Alive?true
Four:5
One:5
Three:5
Two:4
One:4
Four:4
Three:4
Two:3
Four:3
One:3
Three:3
Two:2
Four:2
One:2
Three:2
Two:1
Four:1
One:1
Three:1
Two Exiting
One Exiting
Four Exiting
Three Exiting
completed all four threads
Thread One Alive?false
Thread Two Alive?false
Thread Three Alive?false
Thread Four Alive?false
main thread Exiting

You may also like to read:
What is Thread pool
How to avoid deadlocks in threads
What is a thread
Start a child thread, from another child thread