What is the difference between wait() and sleep()?
Both wait() and sleep() methods in Java are used to pause the execution of a thread. However, they differ significantly in their mechanism, purpose, and interaction with locks and monitors.
Overview
In Java's multithreading environment, controlling thread execution is crucial for resource management and synchronization. While both wait() and sleep() temporarily halt a thread, understanding their distinct behaviors—especially concerning object monitors and thread states—is vital for writing correct and efficient concurrent applications.
Key Differences
| Feature | wait() | sleep() |
|---|---|---|
| Class | Object class | Thread class |
| Monitor Release | Releases the monitor/lock | Does NOT release the monitor/lock |
| Usage Context | Used for inter-thread communication (producer-consumer) | Used for introducing a pause for a specific duration |
| Wake Up | Can be woken up by notify() or notifyAll() | Wakes up automatically after the specified time or by interrupt() |
| Synchronization | Must be called inside a synchronized block/method | Can be called anywhere |
| Argument | Takes an optional timeout (long) | Takes a mandatory time (long) |
| Static/Non-static | Non-static | Static |
wait() method
- Belongs to the Object class.
- Must be called from within a synchronized block or method, otherwise it throws an IllegalMonitorStateException.
- When wait() is called, the current thread releases the lock it holds on the object and goes into a waiting state.
- It can be woken up by another thread calling notify() or notifyAll() on the same object, or if the specified timeout expires.
- Primarily used for inter-thread communication, often in producer-consumer scenarios.
public class WaitExample {
private final Object monitor = new Object();
private boolean messageReady = false;
private String message = null;
public void producer() {
synchronized (monitor) {
System.out.println("Producer: Producing message...");
this.message = "Hello from producer!";
this.messageReady = true;
monitor.notify(); // Notify waiting consumer
System.out.println("Producer: Message produced and notified.");
}
}
public void consumer() {
synchronized (monitor) {
while (!messageReady) {
try {
System.out.println("Consumer: Message not ready, waiting...");
monitor.wait(); // Release monitor and wait
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("Consumer: Interrupted while waiting.");
}
}
System.out.println("Consumer: Received message: " + message);
}
}
public static void main(String[] args) throws InterruptedException {
WaitExample example = new WaitExample();
Thread producerThread = new Thread(example::producer);
Thread consumerThread = new Thread(example::consumer);
consumerThread.start();
Thread.sleep(100); // Give consumer a chance to start and wait
producerThread.start();
producerThread.join();
consumerThread.join();
}
}
sleep() method
- Belongs to the Thread class and is a static method.
- Can be called from any part of the code, not necessarily within a synchronized block.
- When sleep() is called, the current thread temporarily stops execution for a specified duration but DOES NOT release any locks it holds.
- After the specified time, the thread automatically moves back to the runnable state.
- It's typically used to introduce a pause or delay in thread execution.
public class SleepExample {
public static void main(String[] args) {
System.out.println("Main Thread: Starting...");
try {
System.out.println("Main Thread: Going to sleep for 2 seconds.");
Thread.sleep(2000); // Sleep for 2000 milliseconds (2 seconds)
System.out.println("Main Thread: Woke up after 2 seconds.");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("Main Thread: Interrupted while sleeping.");
}
System.out.println("Main Thread: Exiting.");
}
}
Conclusion
The fundamental distinction between wait() and sleep() lies in their lock handling. wait() is essential for proper inter-thread communication, releasing the monitor to allow other threads to acquire it. sleep() on the other hand, is a simple time-based pause that retains all acquired locks, making it suitable for delays rather than coordination.