Java Inter Thread Communication
Inter thread communication is the concept where two or more threads communicate to solve the problem of polling. In java, polling is the situation to check some condition repeatedly, to take appropriate action, once the condition is true. That means, in inter-thread communication, a thread waits until a condition becomes true such that other threads can execute its task. The inter-thread communication allows the synchronized threads to communicate with each other.
Java provides the following methods to achieve inter thread communication.
- wait( )
- notify( )
- notifyAll( )
The following table gives detailed description about the above methods.
Method | Description |
---|---|
void wait( ) | It makes the current thread to pause its execution until other thread in the same monitor calls notify( ) |
void notify( ) | It wakes up the thread that called wait( ) on the same object. |
void notifyAll() | It wakes up all the threads that called wait( ) on the same object. |
🔔 Calling notify( ) or notifyAll( ) does not actually give up a lock on a resource.
Let's look at an example problem of producer and consumer. The producer produces the item and the consumer consumes the same. But here, the consumer can not consume until the producer produces the item, and producer can not produce until the consumer consumes the item that already been produced. So here, the consumer has to wait until the producer produces the item, and the producer also needs to wait until the consumer consumes the same. Here we use the inter-thread communication to implement the producer and consumer problem.
The sample implementation of producer and consumer problem is as follows.
class ItemQueue {
int item;
boolean valueSet = false;
synchronized int getItem()
{
while (!valueSet)
try {
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
System.out.println("Consummed:" + item);
valueSet = false;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
notify();
return item;
}
synchronized void putItem(int item) {
while (valueSet)
try {
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
this.item = item;
valueSet = true;
System.out.println("Produced: " + item);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
notify();
}
}
class Producer implements Runnable{
ItemQueue itemQueue;
Producer(ItemQueue itemQueue){
this.itemQueue = itemQueue;
new Thread(this, "Producer").start();
}
public void run() {
int i = 0;
while(true) {
itemQueue.putItem(i++);
}
}
}
class Consumer implements Runnable{
ItemQueue itemQueue;
Consumer(ItemQueue itemQueue){
this.itemQueue = itemQueue;
new Thread(this, "Consumer").start();
}
public void run() {
while(true) {
itemQueue.getItem();
}
}
}
class ProducerConsumer{
public static void main(String args[]) {
ItemQueue itemQueue = new ItemQueue();
new Producer(itemQueue);
new Consumer(itemQueue);
}
}
When we run this code, it produce the following output.
🔔 All the methods wait( ), notify( ), and notifyAll( ) can be used only inside the synchronized methods only.