Last Updated : 18 Apr, 2025
Inter-thread communication in Java is a mechanism in which a thread is paused from running in its critical section, and another thread is allowed to enter (or lock) the same critical section to be executed.
Note: Inter-thread communication is also known as Cooperation in Java.
What is Polling, and What are the Problems with it?The process of testing a condition repeatedly till it becomes true is known as polling. Polling is usually implemented with the help of loops to check whether a particular condition is true or not. If it is true, a certain action is taken. For example, in a classic queuing problem where one thread is producing data, and the other is consuming it.
Problem with Polling:
How does Java Multi-Threading Tackle this problem?
To avoid polling, Java uses three methods, namely, wait(), notify(), and notifyAll(). All these methods belong to the object class, so all classes have them. They must be used within a synchronized block only.
The image below demonstrates the concept of Thread Synchronization and Inter-Thread Communication in Java:
Producer-Consumer ProblemNow, we are going to understand what producer-consumer problem is. In this one thread add items to a queue and the another thread removes items from the queue. We are going to use wait(), notify() and nortifyAll() methods to ensure that both threads operate efficiently
Example: A simple Java program to demonstrate the three methods. Please note that this program might only run in offline IDEs as it contains taking input at several points.
Java
import java.util.LinkedList;
import java.util.Queue;
public class Geeks {
// Shared queue used by both producer and consumer
private static final Queue<Integer> queue = new LinkedList<>();
// Maximum capacity of the queue
private static final int CAPACITY = 10;
// Producer task
private static final Runnable producer = new Runnable() {
public void run() {
while (true) {
synchronized (queue) {
// Wait if the queue is full
while (queue.size() == CAPACITY) {
try {
System.out.println("Queue is at max capacity");
queue.wait(); // Release the lock and wait
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// Add item to the queue
queue.add(10);
System.out.println("Added 10 to the queue");
queue.notifyAll(); // Notify all waiting consumers
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
// Consumer task
private static final Runnable consumer = new Runnable() {
public void run() {
while (true) {
synchronized (queue) {
// Wait if the queue is empty
while (queue.isEmpty()) {
try {
System.out.println("Queue is empty, waiting");
queue.wait(); // Release the lock and wait
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// Remove item from the queue
System.out.println("Removed " + queue.remove() + " from the queue");
queue.notifyAll(); // Notify all waiting producers
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
public static void main(String[] args) {
System.out.println("Main thread started");
// Create and start the producer thread
Thread producerThread = new Thread(producer, "Producer");
// Create and start the consumer thread
Thread consumerThread = new Thread(consumer, "Consumer");
producerThread.start();
consumerThread.start();
System.out.println("Main thread exiting");
}
}
Explanation of the above Program:
Queue Initialization:
private static final Queue<Integer> queue = new LinkedList<>();
private static final int CAPACITY = 10;
A shared queue (LinkedList implementation) is defined with a capacity of 10. This queue will be used by both producer and consumer threads to add and remove items.
Producer Runnable:
private static final Runnable producer = new Runnable() {
public void run() {
while (true) {
synchronized (queue) {
while (queue.size() == CAPACITY) {
try {
System.out.println("Queue is at max capacity");
queue.wait(); // Release the lock and wait
} catch (InterruptedException e) {
e.printStackTrace();
}
}
queue.add(10);
System.out.println("Added 10 to the queue");
queue.notifyAll(); // Notify all waiting consumers
try {
Thread.sleep(2000); // Simulate some delay in production
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
Consumer Runnable:
private static final Runnable consumer = new Runnable() {
public void run() {
while (true) {
synchronized (queue) {
while (queue.isEmpty()) {
try {
System.out.println("Queue is empty, waiting");
queue.wait(); // Release the lock and wait
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Removed " + queue.remove() + " from the queue");
queue.notifyAll(); // Notify all waiting producers
try {
Thread.sleep(2000); // Simulate some delay in consumption
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
Main Method:
public static void main(String[] args) {
System.out.println("Main thread started");
// Create and start the producer thread
Thread producerThread = new Thread(producer, "Producer");
// Create and start the consumer thread
Thread consumerThread = new Thread(consumer, "Consumer");
producerThread.start();
consumerThread.start();
System.out.println("Main thread exiting");
}
Thread producerThread = new Thread(producer, "Producer")
Thread consumerThread = new Thread(consumer, "Consumer")
producerThread.start()
consumerThread.start()
The program will produce output similar to this:
Main thread started
Main thread exiting
Queue is empty, waiting
Added 10 to the queue
Removed 10 from the queue
Queue is empty, waiting
Added 10 to the queue
Removed 10 from the queue
...
Here, the output demonstrates the interaction between the producer and consumer. The producer adds items to the queue, and the consumer removes them, if the queue is full the producer waits and if the queue is empty the consumer waits. This show how two thread commuincate with each other without wasting time using wait() and notifyAll().
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4