I get exception when using Thread.sleep(x) or wait()
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Thread.sleep(...) and wait() both pause execution, but they are not interchangeable and they fail for different reasons. If you are seeing an exception around either one, the usual causes are InterruptedException for both methods and IllegalMonitorStateException specifically for wait() when it is called without owning the correct monitor.
sleep() and wait() Solve Different Problems
Thread.sleep(...) pauses the current thread for a period of time. It does not release any monitor locks that the thread already holds.
wait() is part of Java's monitor-based coordination model. It must be called on an object whose monitor the current thread already owns, and it releases that monitor while waiting.
That difference is why sleep() is about time, while wait() is about coordination.
Why InterruptedException Happens
Both sleep() and wait() can throw InterruptedException because another thread can interrupt the current thread while it is blocked. This is not necessarily an error in the sense of broken code. It is part of Java's cancellation and coordination model.
A correct handling pattern usually looks like this:
Re-setting the interrupted flag matters because the exception clears it. If you swallow the exception and continue as if nothing happened, higher-level shutdown or cancellation logic may break.
Why wait() Also Throws IllegalMonitorStateException
wait(), notify(), and notifyAll() must be called while synchronized on the same object. If you call wait() without owning that object's monitor, Java throws IllegalMonitorStateException.
Broken example:
Correct version:
This is the biggest source of confusion when people switch from sleep() to wait().
Use wait() in a Condition Loop
wait() should almost always be placed inside a loop that rechecks the condition:
The loop matters because:
- wakeups can be spurious
- another thread may consume the condition first
- waking up does not guarantee the condition is now true
So if is usually wrong here. Use while.
When sleep() Is the Wrong Tool
A common beginner mistake is using Thread.sleep(...) to wait for another thread's state to change:
That is fragile because it waits for time, not for a real condition. If the other thread is slower than expected, the code still fails. If it is faster, you wasted time.
When coordination is the real goal, prefer:
- '
wait()andnotify' - '
CountDownLatch' - '
BlockingQueue' - '
Semaphore' - higher-level concurrency utilities from
java.util.concurrent
A Better Alternative with CountDownLatch
For simple one-time signaling, CountDownLatch is often clearer than manual wait():
This avoids monitor mistakes and reads more directly.
Common Pitfalls
- Calling
wait()without synchronizing on the same object causesIllegalMonitorStateException. - Catching
InterruptedExceptionand ignoring it loses the cancellation signal. - Using
sleep()as a crude synchronization tool makes concurrency timing fragile. - Using
ifinstead ofwhilearoundwait()can break under spurious wakeups. - Forgetting that
sleep()does not release locks whilewait()does.
Summary
- '
Thread.sleep(...)waits for time, whilewait()waits for a condition tied to an object's monitor.' - Both methods can throw
InterruptedException. - '
wait()also requires the current thread to own the target monitor.' - Restore the interrupt flag when catching
InterruptedExceptionunless you have a deliberate reason not to. - Prefer real coordination primitives over
sleep()when another thread's state is what actually matters.

