There are three overloaded Object.wait()
methods in Java are used to pause the execution of the current thread until it is awakened, typically by being notified or interrupted.
Table of Contents
- Introduction
wait()
Method Syntaxfinal void wait()
final void wait(long timeoutMillis)
final void wait(long timeoutMillis, int nanos)
- Examples
- Basic Waiting and Notification
- Waiting with Timeout
- Real-World Use Case
- Conclusion
Introduction
The Object.wait()
methods are members of the Object
class in Java. These methods cause the current thread to wait until another thread invokes the notify()
or notifyAll()
methods for this object, or some other thread interrupts the current thread, or a specified amount of time has elapsed.
wait()() Method Syntax
final void wait()
The syntax for the wait()
method without parameters is as follows:
public final void wait() throws InterruptedException
This method causes the current thread to wait indefinitely until it is notified or interrupted.
final void wait(long timeoutMillis)
The syntax for the wait()
method with a timeout in milliseconds is as follows:
public final void wait(long timeoutMillis) throws InterruptedException
This method causes the current thread to wait until it is notified, interrupted, or the specified timeout elapses.
final void wait(long timeoutMillis, int nanos)
The syntax for the wait()
method with a timeout in milliseconds and nanoseconds is as follows:
public final void wait(long timeoutMillis, int nanos) throws InterruptedException
This method causes the current thread to wait until it is notified, interrupted, or the specified timeout elapses.
Examples
Basic Waiting and Notification
To use the wait()
method, a thread must acquire the object's monitor by synchronizing on it. The notify()
method is used to wake up a waiting thread.
Example
class WaitNotifyExample {
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) {
WaitNotifyExample example = new WaitNotifyExample();
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.
Waiting with Timeout
The wait(long timeoutMillis)
method can be used to wait with a specified timeout.
Example
class WaitTimeoutExample {
private final Object lock = new Object();
public void waitingMethod() {
synchronized (lock) {
try {
System.out.println("Waiting thread is going to wait for 2 seconds...");
lock.wait(2000);
System.out.println("Waiting thread is resumed or timed out.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void notifyingMethod() {
synchronized (lock) {
try {
Thread.sleep(1000); // Simulate some work
} catch (InterruptedException e) {
e.printStackTrace();
}
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) {
WaitTimeoutExample example = new WaitTimeoutExample();
Thread waitingThread = new Thread(example::waitingMethod);
Thread notifyingThread = new Thread(example::notifyingMethod);
waitingThread.start();
notifyingThread.start();
}
}
Output:
Waiting thread is going to wait for 2 seconds...
Notifying thread is going to notify...
Notifying thread has called notify.
Waiting thread is resumed or timed out.
Real-World Use Case
Producer-Consumer Problem with Timeout
In a real-world scenario, the wait(long timeoutMillis)
method can be used to solve the producer-consumer problem where producers put items into a shared resource and consumers take items out. The wait()
method can be used to make consumers wait for items and producers wait for space to be available, with a timeout to prevent indefinite waiting.
Example
import java.util.LinkedList;
import java.util.Queue;
class ProducerConsumerTimeoutExample {
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) {
System.out.println("Queue is full. Producer is waiting...");
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()) {
System.out.println("Queue is empty. Consumer is waiting...");
lock.wait(2000);
System.out.println("Consumer waited for 2 seconds or was notified.");
}
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) {
ProducerConsumerTimeoutExample example = new ProducerConsumerTimeoutExample();
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
Queue is empty. Consumer is waiting...
Consumer waited for 2 seconds or was notified.
Produced: 2
...
Conclusion
These three overloaded Object.wait()
methods in Java provide a powerful mechanism for thread communication and synchronization. By understanding how to use these methods, you can effectively coordinate activities between multiple threads. Whether you are using the basic wait()
method, the wait(long timeoutMillis)
method with a timeout, or solving complex scenarios like the producer-consumer problem, the wait()
methods offer a reliable way to manage thread interactions in Java applications.
Comments
Post a Comment
Leave Comment