What is Inter-Thread Communication in Java?

Inter-Thread Communication


 Inter-thread communication in Java is a technique through which multiple threads communicate with each other by reducing the amount of idle time. A thread exchanges information before or after it changes its state.

 

In other words, if two threads are executing simultaneously, it is important that they communicate with each other. For instance, if two threads A and B have multiple tasks, it is better if they communicate with each other instead of waiting for each other to complete their tasks. Thus, It prevents the wastage of the CPU cycles. This type of information exchange between threads is called inter-thread communication in Java.

 


 How can this be achieved?

 It is implemented using three methods provided by the Object class of java.lang package which is as follows:

·       wait()

·       notify()

·       notifyAll()

These methods can only be called from a method or a block of code that is synchronized. If the method has an exception, then it should be thrown. Since it throws a checked exception, therefore, these methods must be used within the Java try-catch block.

 


wait() method in Java

The wait method causes the current thread to wait for another thread to call the notify() method or the notifyAll() method for this object. It does so until the current thread has already executed the synchronized method. A thread can wait for the maximum time if the time is specified inside the method.

 

Various forms of wait() method can be used to define the amount of time that a thread can wait. They are as follows:

·       public final void wait()

·       public final void wait(long millisecond) throws InterruptedException

·       public final void wait(long millisecond, long nanosecond) throws InterruptedException







notify() method in Java


The notify() method awakens a single thread that is waiting on the object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The decision is self-assertive and occurs at the discretion of the implementation.

public final void notify()

 

notifyAll() method in Java

The notifyAll() method is used to awaken all threads that called the wait() method on the same object. The thread having the highest priority will run first.

public final void notifyAll()  


Understanding the Process



The clarification of the above figure is as per the following:

  1.  Threads enter to gain lock.
  2.   Lock is procured by on thread.
  3.   Now thread goes to waiting state if you call wait() method on the object. Otherwise, it releases the lock and exits.
  4.   If you call notify() or notifyAll() method, the thread moves to the runnable state.
  5.   Presently thread is accessible to obtain the lock.
  6.   After completion of the task, the thread discharges the lock and exits the monitor state of the object.

Example:

Let us take an example where a thread uses data delivered by another thread using the wait() and notify() method.

 

Code:

public class A

{

 int i;  

 boolean flag = false; // flag will be true when data production is over.

synchronized void deliver(int i)

{

 if(flag)

 try

 {

  wait(); // Wait till a notification is received from Thread2. There will be no wastage of time.     

 }

 catch(InterruptedException ie)

 {

  System.out.println(ie);     

 }

   this.i = i;     

   flag = true; // When data production is over, it will store true into flag.

   System.out.println("Data Delivered: " +i);

   notify(); // When data production is over, it will notify Thread2 to use it.

 }

synchronized int receive()

{

if(!flag)

try {

 wait(); // Wait till a notification is received from Thread1.      

}

catch(InterruptedException ie){

 System.out.println(ie);      

}

 System.out.println("Data Received: " + I);

  flag = false; // It will store false into flag when data is received.

  notify(); // When data received is over, it will notify Thread1 to produce next data.

  return i;

 }

}

public class Thread1 extends Thread

{

 A obj;

 Thread1(A obj)

 {

  this.obj = obj;

 }

public void run()

{

for(int j = 1; j <= 5; j++){

 obj.deliver(j);           

  }

}}

public class Thread2 extends Thread

{

A obj;

Thread2(A obj)

{

 this.obj = obj;

}

public void run()

{

for(int k = 0; k <= 5; k++){

 obj.receive();          

}

 }

}

public class Communication

{

public static void main(String[] args)

{

 A obj = new A(); // Creating an object of class A.

 

// Creating two thread objects and pass reference variable obj as parameter to Thread1 and Thread2.

Thread1 t1 = new Thread1(obj);

Thread2 t2 = new Thread2(obj);

// Run both threads.

  t1.start();

  t2.start();

 }

}

 

Output:

Data Delivered: 1

      Data Received: 1

      Data Delivered: 2

      Data Received: 2

      Data Delivered: 3

      Data Received: 3

      Data Delivered: 4

      Data Received: 4

      Data Delivered: 5

      Data Received: 5

Explanation:

1. In this example program, wait() and notify() methods are called inside deliver() and receive() method. Both methods enable Thread1 to notify Thread2 after producing data and wait until Thread2 is complete using.

2. In the same way, Thread2 after using data notifies Thread1 and waits until Thread1 produces and delivers the next data. Thus, the output comes in a synchronized form.

3. If the flag is true, Thread2 takes data from Thread1 and uses it. When Thread1 is busy producing data, now and then Thread2 will check flag is true or not.

If the flag shows false, then Thread2 will wait for the object until it receives a notification from a notify() method.

When the data production is over, Thread1 will send a notification immediately to Thread2 to receive data. In this way, Thread1 and Thread2 communicate with each other efficiently.

 

Why wait(), notify() and notifyAll() methods are defined in Object class not Thread class?

This is because all these three methods are related to lock and Java provides lock at the Object level, not at the Thread level. Therefore, they are defined in the Object class.



Hope you found this article useful enough to gain some clarity over the concept of inter-thread communication. If you wish to suggest to me some new facts and ideas about the topic or would like to correct me somewhere, feel free to leave a comment below. I’d love to know what you think!

Thanks for reading!!!


Related Article: Synchronization in Java

Comments