The Object.notify()
method in Java is used for thread communication, specifically in the context of multithreading and synchronization.
Table of Contents
- Introduction
notify()
Method Syntax- Examples
- Basic Notification
- Using
notify()
withwait()
- Real-World Use Case
- Conclusion
Introduction
The Object.notify()
method is a member of the Object
class in Java. It is used to wake up a single thread that is waiting on the object's monitor. If multiple threads are waiting on this object's monitor, one of them is chosen to be awakened. The exact thread chosen is not specified and depends on the implementation of the JVM.
notify()() Method Syntax
The syntax for the notify()
method is as follows:
public final void notify()
This method does not return any value and throws an IllegalMonitorStateException
if the current thread is not the owner of the object's monitor.
Examples
Basic Notification
To use the notify()
method, you need to have a thread that calls wait()
on the object's monitor and another thread that calls notify()
to wake it up.
Example
class NotifyExample {
private final Object lock = new Object();
public void waitingMethod() {
synchronized (lock) {
try {
System.out.println("Waiting thread is going to wait...");
lock.wait();
System.out.println("Waiting thread is resumed.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void notifyingMethod() {
synchronized (lock) {
System.out.println("Notifying thread is going to notify...");
lock.notify();
System.out.println("Notifying thread has called notify.");
}
}
public static void main(String[] args) {
NotifyExample example = new NotifyExample();
Thread waitingThread = new Thread(example::waitingMethod);
Thread notifyingThread = new Thread(example::notifyingMethod);
waitingThread.start();
try {
// Ensure the waiting thread starts waiting before the notifying thread calls notify
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
notifyingThread.start();
}
}
Output:
Waiting thread is going to wait...
Notifying thread is going to notify...
Notifying thread has called notify.
Waiting thread is resumed.
Using notify()
with wait()
The notify()
method is typically used in conjunction with the wait()
method to coordinate activities between threads.
Example
class SharedResource {
private final Object lock = new Object();
private boolean conditionMet = false;
public void waitingMethod() {
synchronized (lock) {
while (!conditionMet) {
try {
System.out.println("Waiting thread is going to wait...");
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Condition met. Waiting thread is resumed.");
}
}
public void notifyingMethod() {
synchronized (lock) {
conditionMet = true;
System.out.println("Notifying thread is going to notify...");
lock.notify();
System.out.println("Notifying thread has called notify.");
}
}
public static void main(String[] args) {
SharedResource resource = new SharedResource();
Thread waitingThread = new Thread(resource::waitingMethod);
Thread notifyingThread = new Thread(resource::notifyingMethod);
waitingThread.start();
try {
// Ensure the waiting thread starts waiting before the notifying thread calls notify
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
notifyingThread.start();
}
}
Output:
Waiting thread is going to wait...
Notifying thread is going to notify...
Notifying thread has called notify.
Condition met. Waiting thread is resumed.
Real-World Use Case
Producer-Consumer Problem
In a real-world scenario, the notify()
method can be used to solve the producer-consumer problem where producers put items into a shared resource and consumers take items out. The notify()
method can be used to notify consumers when items are added and notify producers when space is available.
Example
import java.util.LinkedList;
import java.util.Queue;
class ProducerConsumerExample {
private final Queue<Integer> queue = new LinkedList<>();
private final int MAX_SIZE = 5;
private final Object lock = new Object();
public void produce() throws InterruptedException {
int value = 0;
while (true) {
synchronized (lock) {
while (queue.size() == MAX_SIZE) {
lock.wait();
}
queue.offer(value);
System.out.println("Produced: " + value);
value++;
lock.notify();
}
Thread.sleep(1000); // Simulate time taken to produce an item
}
}
public void consume() throws InterruptedException {
while (true) {
synchronized (lock) {
while (queue.isEmpty()) {
lock.wait();
}
int value = queue.poll();
System.out.println("Consumed: " + value);
lock.notify();
}
Thread.sleep(1000); // Simulate time taken to consume an item
}
}
public static void main(String[] args) {
ProducerConsumerExample example = new ProducerConsumerExample();
Thread producerThread = new Thread(() -> {
try {
example.produce();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread consumerThread = new Thread(() -> {
try {
example.consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
producerThread.start();
consumerThread.start();
}
}
Output:
Produced: 0
Consumed: 0
Produced: 1
Consumed: 1
Produced: 2
Consumed: 2
...
Conclusion
The Object.notify()
method in Java is a crucial tool for thread communication and synchronization. By understanding how to use this method, you can coordinate activities between multiple threads effectively. Whether you are using it for basic notification, coordinating with wait()
, or implementing complex scenarios like the producer-consumer problem, the notify()
method provides a powerful mechanism for managing thread interactions in Java applications.
Comments
Post a Comment
Leave Comment