Use a CountDownLatch instead. A java.util.concurrent.CountDownLatch allows one or more threads to wait for some operation(s) to complete.
A CountDownLatch is initialized with a given count. Threads that need to wait for some condition/operation (for the count to reach zero), call one of the await() methods. The count is decremented from the thread that completed some operation by invoking the countdown() method. Then, all waiting threads continue execution.
Example
// create latch with count of one (1)
CountDownLatch latch = new CountDownLatch(1);
// create instances of classes that implement Runnable
Waiter waiter = new Waiter(latch);
Worker worker = new Worker(latch);
// start threads
new Thread(waiter).start();
new Thread(worker).start();
Define Waiter Runnable (waits for some operation to complete)
public class Waiter implements Runnable{
CountDownLatch latch = null;
public Waiter(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
try {
// wait for the latch to be released
latch.await();
} catch (InterruptedException e) {
// set interupt flag
Thread.currentThread().interrupt();
// log interrupt
System.out.println("Interrupted");
}
System.out.println("Unblocked");
doSomething();
}
}
Define Worker Runnable (executes some operation)
public class Worker implements Runnable {
CountDownLatch latch = null;
public Worker(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
// do some job
// when ready release latch
latch.countDown();
System.out.println("Latch Released");
}
}
Avoid
Using the old wait-notify java API. The reason is the spurious wakeups. That is your thread wakes up without being actually notified, so you have to check that your condition is satisfied or else keep waiting.
Spurious wakeups from javadocs
A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup. While this will rarely occur in practice, applications must guard against it by testing for the condition that should have caused the thread to be awakened, and continuing to wait if the condition is not satisfied. In other words, waits should always occur in loops, like this one:
synchronized (obj) {
while (<condition does not hold>)
obj.wait(timeout);
... // Perform action appropriate to condition
}
(For more information on this topic, see Section 3.2.3 in Doug Lea's "Concurrent Programming in Java (Second Edition)" (Addison-Wesley, 2000), or Item 50 in Joshua Bloch's "Effective Java Programming Language Guide" (Addison-Wesley, 2001).