Back to: Java Tutorials For Beginners and Professionals
Inter Thread Communication in Java
In this article, I am going to discuss Inter Thread Communication in Java with examples. Please read our previous article where we discussed Thread Synchronization in Java. At the end of this article, you will understand how multiple threads communicate with each other in java with examples.
Inter-Thread Communication (Cooperation) in Java:
It is a mechanism of communication between two threads or multiple threads that acts on the common object (owner). To perform the multiple actions at a time we need Inter-thread communication.
For example online video players, audio players, etc. In both types of players generally, there are two types of threads: Buffer Thread and Playing Thread.
The buffer Thread is responsible to download content from the server into a buffer memory and whereas the playing thread is responsible to play content and these actions will be done based on thread communication only.
Methods in object class to perform Inter-Thread Communication:
- wait(): This method is used to make the particular Thread wait until it gets a notification. This method pauses the current thread to the waiting room dynamically.
- notify(): This method is used to send the notification to one of the waiting thread so that thread enters into a running state and execute the remaining task. This method wakeup a single thread into the active state (that acts on the common object).
- notifyAll(): This method is used to send the notification to all the waiting threads so that all thread enters into the running state and execute simultaneously. This method wakes up all the waiting threads that act on the common objects.
Note: All these three methods are available in the Object class which is super most class so we can access all these three methods in any class directly without any reference. These methods are mainly used to perform Inner-Thread Communication. By using these methods we can resolve problems like Producer-Consumer problems, Reader-Writer problems, etc…..
Example to demonstrate Inner Thread Communication in Java
class MyThread implements Runnable { int total; public void run () { for (int i = 1; i <= 1000; i++) { total = total + i; if (total > 10000) { synchronized (this) { notify (); } } try { Thread.sleep (5); } catch (InterruptedException ie) { } } System.out.println ("User Thread total:" + total); } } public class InnerThreadDemo { public static void main (String[]args) { MyThread mt = new MyThread (); Thread t = new Thread (mt); t.start (); try { synchronized (mt) { mt.wait (); } } catch (InterruptedException ie) { } System.out.println ("Main Thread total:" + mt.total); } }
Output:
Note: We must call wait(), notify() and notifyAll() methods inside the synchronized blocks or synchronized methods, otherwise it will throw a Runtime Exception called IllegalMonitorStateException.
What is the difference between notify() and notifyAll()?
notify() wakes up only one thread and it follows thread priority. notifyAll() wakes up multiple threads and it does not follow thread priority.
Explain the reason why wait(), notify() and notifyAll() belong to the object class instead of the thread class?
According to the Inter-thread communication rule, the owner must be common to the multiple threads. In Java, the owner can be any Java class object. To make these methods available in any type of owner, Java defines those methods in object class because it is a supreme class for all owners.
Producer-Consumer Problem
Problem:
There are two processes, a producer and a consumer, that share a common buffer with a limited size. The producer “produces” data and stores it in the buffer, and the consumer “consumes” the data, removing it from the buffer. Having two processes that run in parallel, we need to make sure that the producer will not put new data in the buffer when the buffer is full and the consumer won’t try to remove data from the buffer if the buffer is empty.
Solution:
For solving this concurrency problem, the producer and the consumer will have to communicate with each other. If the buffer is full, the producer will go to sleep and will wait to be notified. After the consumer will remove some data from the buffer, it will notify the producer, and then, the producer will start refilling the buffer again. The same process will happen if the buffer is empty, but in this case, the consumer will wait to be notified by the producer.
If this communication is not done properly, it can lead to a deadlock where both processes will wait for each other.
Classic Approach:
class ShowRoom { int value; boolean pro_thread = true; synchronized void produce (int i) { if (pro_thread == true) { value = i; System.out.println ("Producer has produced Product " + value); pro_thread = false; notify (); } try { wait (); } catch (InterruptedException ie) { } } synchronized int consume () { if (pro_thread == true) { try { wait(); } catch (InterruptedException ie) { } } pro_thread = true; notify (); return value; } } class Producer implements Runnable { ShowRoom sr; Producer (ShowRoom sr) { this.sr = sr; } public void run () { int i = 1; for (i = 1; i <= 10; i++) { sr.produce (i); try { Thread.sleep (1000); } catch (InterruptedException ie) { } } } } class Consumer implements Runnable { ShowRoom sr; Consumer (ShowRoom sr) { this.sr = sr; } public void run () { while (true) { int res = sr.consume (); System.out.println ("Consumer has taken product " + res); try { Thread.sleep (1000); } catch (InterruptedException ie) { } } } } public class ProducerConsumer { public static void main (String[]args) { ShowRoom sr = new ShowRoom (); Producer p = new Producer (sr); Consumer c = new Consumer (sr); Thread t1 = new Thread (p); Thread t2 = new Thread (c); t1.start (); t2.start (); } }
Output:
In the next article, I am going to discuss Deadlock in Java with Examples. Here, in this article, I try to explain Inter Thread Communication in Java with examples. I hope you enjoy this Inter Thread Communication in Java with Examples article.