1. Overview
In this short article, we’ll have a look at the standard sleep() and wait() methods in core Java, and understand the differences and similarities between them.
2. General Differences Between Wait and Sleep
Simply put, wait() is an instance method that’s used for thread synchronization.
It can be called on any object, as it’s defined right on java.lang.Object, but it can only be called from a synchronized block. It releases the lock on the object so that another thread can jump in and acquire a lock.
On the other hand, Thread.sleep() is a static method that can be called from any context. Thread.sleep() pauses the current thread and does not release any locks.
Here’s a very simplistic initial look at these two core APIs in action:
private static Object LOCK = new Object();
private static void sleepWaitExamples()
throws InterruptedException {
Thread.sleep(1000);
System.out.println(
"Thread '" + Thread.currentThread().getName() +
"' is woken after sleeping for 1 second");
synchronized (LOCK) {
LOCK.wait(1000);
System.out.println("Object '" + LOCK + "' is woken after" +
" waiting for 1 second");
}
}
Running this example will produce the following output:
Thread ‘main’ is woken after sleeping for 1 second
Object ‘java.lang.Object@31befd9f’ is woken after waiting for 1 second
3. Waking up Wait and Sleep
When we use the sleep() method, a thread gets started after a specified time interval, unless it is interrupted.
For wait(), the waking up process is a bit more complicated. We can wake the thread by calling either the notify() or notifyAll() methods on the monitor that is being waited on.
Use notifyAll() instead of notify() when you want to wake all threads that are in the waiting state. Similarly to the wait() method itself, notify(), and notifyAll() have to be called from the synchronized context.
For example, here’s how you can wait:
synchronized (b) {
while (b.sum == 0) {
System.out.println("Waiting for ThreadB to complete...");
b.wait();
}
System.out.println("ThreadB has completed. " +
"Sum from that thread is: " + b.sum);
}
And then, here’s how another thread can then wake up the waiting thread – by calling notify() on the monitor:
int sum;
@Override
public void run() {
synchronized (this) {
int i = 0;
while (i < 100000) {
sum += i;
i++;
}
notify();
}
}
Running this example will produce the following output:
Waiting for ThreadB to complete…
ThreadB has completed. Sum from that thread is: 704982704
4. Conclusion
This is a quick primer to the semantics of wait and sleep in Java.
In general, we should use sleep() for controlling execution time of one thread and wait() for multi-thread-synchronization. Naturally, there’s a lot more to explore – after understanding the basics well.
As always, you can check out the examples provided in this article over on GitHub.