What is the difference between wait() and sleep() in Java?
wait() and sleep() both pause thread execution, but they serve entirely different purposes and behave very differently with respect to locks.
sleep(long millis) is a static method on Thread. It suspends the current thread for the specified duration, or until interrupted. Critically, sleep() does not release any locks or monitors the thread holds. It is used for rate limiting, polling delays, or scheduling — it has nothing to do with inter-thread coordination.
wait() is an instance method on Object. It must be called from within a synchronized block on the object being waited on. When called, it atomically releases the monitor lock on that object and suspends the thread. The thread remains suspended until another thread calls notify() or notifyAll() on the same object, or until the optional timeout expires. After being notified, the thread re-acquires the lock before proceeding.
This atomic release-and-wait property is why wait() is used for condition-based coordination. The classic producer-consumer pattern: the consumer calls synchronized(queue) { while (queue.isEmpty()) queue.wait(); }, releasing the lock so the producer can enter the synchronized block and call queue.notifyAll().
Both methods throw InterruptedException, which must be handled. Both should be called in a while loop that re-checks the condition, not an if statement — to guard against spurious wakeups (OS-level interruptions where wait() returns without being notified).
In modern Java, wait/notify is largely replaced by higher-level concurrency utilities: Condition (from java.util.concurrent.locks.Lock) provides await()/signal()/signalAll() with the same semantics but more flexibility, and BlockingQueue handles the producer-consumer pattern without any manual synchronization. wait/notify is still important to understand for interviews and when maintaining legacy code.
| Aspect | wait() | sleep() |
|---|---|---|
| Defined on | Object | Thread (static method) |
| Releases lock? | Yes — releases the monitor | No — holds all locks |
| Requires synchronized? | Yes — must be inside synchronized block | No |
| Woken by | notify() / notifyAll() or timeout | Timeout expiry or interrupt |
| Use case | Inter-thread condition coordination | Fixed-duration pause / rate limiting |
| Spurious wakeups | Possible — always use in a while loop | Not applicable |
Correctly states that wait() releases the lock and requires synchronized context, while sleep() does not release locks and is a Thread static method.
Adds the atomic release-and-wait semantics, spurious wakeup issue with while-loop guard, modern alternatives (Condition, BlockingQueue), and gives a concrete use case for each.
Reading the answer is step one. Explaining it unprompted — under interview pressure — is what actually matters. Get AI-graded feedback on your answer with follow-up probes on your weak points.
Get Graded — Free Assessment