When we are using multiple threads in our application, we’ll create the threads and call the start() method on these threads. It’s the Java Virtual Machine that calls the run method of this thread when the resources and CPU are ready. Then the thread will execute the run() method and later transition to terminated state.
Suppose you have a scenario where you want to start further processing only when a thread has ended then how will you know that a thread has ended?
Java multi-threading provides two ways to find that–
- isAlive()
- join()
isAlive() method in Java
isAlive() method is the member of the Thread class and its general form is–
public final boolean isAlive()
isAlive() method tests if the thread it is called upon is alive or not. A thread is alive if it has been started and not yet terminated. The isAlive() method returns true if the thread upon which it is called is still running, otherwise it returns false.
join() method in Java
Join() method is used when you want to wait for the thread to finish. Its general form is–
public final void join() throws InterruptedException
This method waits until the thread on which it is called terminates. There are three overloaded join functions.
- public final void join()- Waits indefinitely for this thread to die.
- public final void join(long millis)-Waits at most millis milliseconds for this thread to die. A timeout of 0 means to wait forever.
- public final void join(long millis, int nanos)- Waits at most millis milliseconds plus nanos nanoseconds for this thread to die.
Java Example code using join and isAlive()
Let’s say there is a scenario where in a code multiple threads are spawned to do some heavy computation and only when the processing is done a message should be displayed to a user that “Processing is done”.
Now first let’s try to do something like this without using join() method.
class MyRunnableClass implements Runnable{ @Override public void run() { for(int i = 0; i < 5 ; i++){ System.out.println(Thread.currentThread().getName() + " i - " + i); try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } public class JoinExample { public static void main(String[] args) { Thread t1 = new Thread(new MyRunnableClass(), "t1"); Thread t2 = new Thread(new MyRunnableClass(), "t2"); Thread t3 = new Thread(new MyRunnableClass(), "t3"); t1.start(); t2.start(); t3.start(); System.out.println("t1 Alive - " + t1.isAlive()); System.out.println("t2 Alive - " + t2.isAlive()); System.out.println("t3 Alive - " + t3.isAlive()); /*try { t1.join(); t2.join(); t3.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("t1 Alive - " + t1.isAlive()); System.out.println("t2 Alive - " + t2.isAlive()); System.out.println("t3 Alive - " + t3.isAlive());*/ System.out.println("Processing finished"); } }
Output
t1 Alive - true t2 Alive - true t3 Alive - true Processing finished t3 i - 0 t1 i - 0 t2 i - 0 t3 i - 1 t1 i - 1 t2 i - 1 t2 i - 2 t1 i - 2 t3 i - 2 t3 i - 3 t1 i - 3 t2 i - 3 t3 i - 4 t1 i - 4 t2 i – 4
Here it can be seen that the message is displayed much before the actual processing has finished.
Now let’s uncomment the code related to join and run the program again.
class MyRunnableClass implements Runnable{ @Override public void run() { for(int i = 0; i < 5 ; i++){ System.out.println(Thread.currentThread().getName() + " i - " + i); try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } public class JoinExample { public static void main(String[] args) { Thread t1 = new Thread(new MyRunnableClass(), "t1"); Thread t2 = new Thread(new MyRunnableClass(), "t2"); Thread t3 = new Thread(new MyRunnableClass(), "t3"); t1.start(); t2.start(); t3.start(); System.out.println("t1 Alive - " + t1.isAlive()); System.out.println("t2 Alive - " + t2.isAlive()); System.out.println("t3 Alive - " + t3.isAlive()); try { t1.join(); t2.join(); t3.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("t1 Alive - " + t1.isAlive()); System.out.println("t2 Alive - " + t2.isAlive()); System.out.println("t3 Alive - " + t3.isAlive()); System.out.println("Processing finished"); } }
Output
t1 Alive - true t2 Alive - true t3 Alive - true t2 i - 0 t3 i - 0 t1 i - 0 t1 i - 1 t2 i - 1 t3 i - 1 t3 i - 2 t1 i - 2 t2 i - 2 t1 i - 3 t2 i - 3 t3 i - 3 t2 i - 4 t3 i - 4 t1 i - 4 t1 Alive - false t2 Alive - false t3 Alive - false Processing finished
Now see how message is displayed only when the processing is actually finished and all the threads are terminated. The second print statements using isAlive() method confirms that the threads are not running any more.
That's all for this topic isAlive() And join() Methods in Java Multi-Threading. If you have any doubt or any suggestions to make please drop a comment. Thanks!
Related Topics
You may also like-
Your blog has good material for Java, multithreading posts are very nicely written and helped me a lot in understanding the concepts.
ReplyDelete