PART 4 · CLASS 20
sleep() vs. wait()
Both sleep() and wait() can pause a thread. But they behave differently, especially when it comes to releasing locks. Let's understand the difference with simple examples.
1. A Quick Introduction
In our previous classes, we learned about two important methods:
sleep()— pauses a thread for a specified time.wait()— makes a thread wait until another thread notifies it, or until it otherwise wakes up.
Both methods can make a thread stop executing temporarily. However, they serve different purposes.
Let's understand them one by one.
2. Understanding sleep()
The sleep() method belongs to the
Thread class.
It pauses the execution of the currently running thread for a specified amount of time.
For example:
public class Main {
public static void main(String[] args)
throws InterruptedException {
System.out.println("Before sleeping");
Thread.sleep(2000);
System.out.println("After sleeping");
}
}
Here, the main thread pauses for approximately two seconds.
The output will be:
Before sleeping
After sleeping
Notice that we called Thread.sleep(2000).
The value is in milliseconds, so 2000 milliseconds
means two seconds.
One important thing to remember:
sleep() does not release any monitor locks
that the thread is holding.
3. Understanding wait()
The wait() method belongs to the
Object class.
It is used when a thread needs to wait for another thread to communicate with it.
When a thread calls wait() on an object,
it releases that object's monitor lock and enters
the waiting state.
It can wake up when another thread calls
notify() or notifyAll()
on the same object.
It can also wake up because of interruption, a spurious wakeup, or a timeout if a timed wait is used.
Remember that wait() must be called while
the current thread owns the monitor lock of that object.
For example:
class SharedResource {
public synchronized void waitForSignal()
throws InterruptedException {
System.out.println("Thread is waiting...");
wait();
System.out.println("Thread resumed!");
}
public synchronized void sendSignal() {
System.out.println("Sending notification...");
notify();
}
}
Here, one thread can call waitForSignal()
and another thread can call sendSignal().
The waiting thread releases the object's monitor when
it calls wait(). The notifying thread can
then acquire that lock, send the notification and
eventually release the lock.
4. The Most Important Difference: Lock Release
This is the most important difference between
sleep() and wait().
Imagine a thread is executing a synchronized method. It has acquired the object's monitor lock.
Now, suppose it pauses its execution.
What happens to the lock depends on which method it uses.
When a thread calls sleep()
- The thread pauses for the specified time.
- It continues holding any monitor locks it already owns.
- Another thread cannot acquire those same locks until they are released.
When a thread calls wait()
- The thread enters the waiting state.
- It releases the monitor lock of the object on which wait() was called.
- Another thread can acquire that object's monitor lock.
- The waiting thread must reacquire the lock before continuing.
Remember: wait() releases only the monitor
lock of the object on which it is called. It does not
automatically release other locks held by the thread.
5. Let's Understand the Difference with an Example
Let's first see what happens when a thread uses
sleep() inside a synchronized method.
class SharedResource {
public synchronized void useResource() {
System.out.println(
Thread.currentThread().getName()
+ " acquired the lock"
);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
System.out.println(
Thread.currentThread().getName()
+ " finished using the resource"
);
}
}
public class Main {
public static void main(String[] args) {
SharedResource resource = new SharedResource();
Thread t1 = new Thread(
resource::useResource, "Thread-1"
);
Thread t2 = new Thread(
resource::useResource, "Thread-2"
);
t1.start();
t2.start();
}
}
Both threads are trying to execute the same synchronized method on the same object.
What happens?
- Thread-1 acquires the object's lock.
- Thread-1 calls sleep() for two seconds.
- Thread-1 pauses but continues holding the lock.
- Thread-2 cannot enter the synchronized method yet.
- Thread-1 wakes up and finishes its work.
- Thread-1 releases the lock when it exits the method.
- Thread-2 can now acquire the lock and execute the method.
This demonstrates that sleep() does not
release the monitor lock.
6. Quick Comparison
Let's put everything together in one simple comparison.
| Feature | sleep() | wait() |
|---|---|---|
| Belongs to | Thread class | Object class |
| Purpose | Pause a thread for some time | Wait for a condition or notification |
| Releases monitor lock? | No | Yes, the lock of the object on which wait() is called |
| How does it wake up? | After the requested time, or earlier if interrupted | Notification, interruption, spurious wakeup, or timeout |
| Must be called inside synchronized code? | No | Yes, while holding the object's monitor lock |
7. When Should We Use Them?
Use sleep() when you simply want a thread
to pause for a particular amount of time.
For example:
- Pausing between repeated operations.
- Creating a simple delay in a demonstration.
- Simulating a time-consuming task in an example.
Use wait() when a thread needs to wait for
another thread to change a shared condition or notify it.
For example:
- A consumer waiting for data from a producer.
- A thread waiting until a shared resource becomes available.
- Threads coordinating their work.
We will explore one of these situations in detail in our upcoming Producer–Consumer classes.
Test Your Understanding
Let's see how well you understood this class!
Question 1: Which class provides the sleep() method?
Question 2: Which class provides the wait() method?
Question 3: What happens to the monitor lock when a thread calls sleep()?
Question 4: What happens when a thread calls wait() on an object?
Question 5: When should we use wait()?
Class Summary
Let's quickly revise what we learned today:
sleep()belongs to the Thread class.wait()belongs to the Object class.sleep()pauses a thread for a specified time.wait()makes a thread wait for a condition or notification.sleep()does not release monitor locks.wait()releases the monitor lock of the object on which it is called.- A thread using wait() must reacquire that lock before continuing.
The most important difference to remember: sleep() pauses a thread without releasing its monitor locks, while wait() releases the monitor lock of the object on which it is called.
You have completed 20 out of 46 classes.