As we all know, the very useful Java Thread methods sleep(), suspend(), and resume() have been deprecated. Many articles online tell us to use a control variable instead, by polling the status of the variable at key points in the run() method. This may be a good idea, but I felt that we could have done better. For example, thread synchronization: what happens if all you need to do is wait for a particular signal to continue? There’s really no point in awakening the thread every x milliseconds just to find out that it should still be sleeping. Just as an analogy: Would you like to wake up every hour to check your email?
Solution: the wait() and notify() methods in a Thread class. To understand why they are named this way, you must first understand the role of locks (aka mutex/semaphore) in thread synchronization. I assume you have a basic understanding of what locks are.
Locks in Java are pretty simple, and you only need to know the synchronized keyword. Each object in Java is its own lock, so you may lock on any variable or object that you have a reference to. If you’re going to use thread synchronization, then it’s most likely that the thread in charge of notify() has is a reference to the other thread. So the waiting thread should put a lock on itself. In terms of code:
// put this code in the thread that should be waiting
synchronized (this) {
wait();
}
You can also set a timeout to wait using wait(int n) so that it continues after that time, regardless of whether it was notify()-ed. This can be a good substitute for sleep(int n) too, if you didn't implement notify() anywhere else
Here's the example code to set you going.
public class TestThreadWait {
public static void main(String[] args) {
final WaitThread w = new WaitThread();
w.start();
final Timer t = new Timer();
TimerTask tt = new TimerTask() {
public void run() {
synchronized (w) {
w.notify();
}
t.cancel();
}
};
t.schedule(tt, 5000);
}
}
class WaitThread extends Thread {
public void run() {
System.out.println("Entering wait, should wake in 5s..");
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Out of wait!");
}
}
