Notified
Invoking the notify() method on an object wakes up a single thread that is waiting for the lock of this object. The selection of a thread to awaken is dependent on the thread policies implemented by the JVM. On being notified, a waiting thread first transits to the BLOCKED state to acquire the lock on the object, and not directly to the READY substate of the RUNNABLE state. The thread is also removed from the wait set of the object. Note that the object lock is not released when the notifying thread invokes the notify() method. The notifying thread releases the lock at its own discretion, and the awakened thread will not be able to run until the notifying thread releases the object lock.
When the notified thread obtains the object lock, it is enabled for execution, waiting in the READY substate for its turn to execute again. Finally, when it does execute, the call to the wait() method returns and the thread can continue with its execution.
From Figure 22.10 we see that thread t2 does not release the object lock when it invokes the notify() method. Thread t1 is forced to wait in the BLOCKED state for lock acquisition. It is shown no privileges, and must compete with any other threads blocked for lock acquisition.
A call to the notify() method has no effect if there are no threads in the wait set of the object.
In contrast to the notify() method, the notifyAll() method wakes up all threads in the wait set of the shared object. They will all transit to the BLOCKED state, and contend for the object lock as explained earlier.
It should be stressed that a program should not make any assumptions about the order in which threads awaken in response to the notify() or notifyAll() method, or transit to the BLOCKED state for lock acquisition.
Timed-out
The wait() call can specify the time the thread should wait before being timed out, if it was not awakened by being notified or interrupted. The timed-out thread transits to the BLOCKED state and competes to acquire the lock as explained above. Note that the awakened thread has no way of knowing whether it was timed out or awakened by one of the notification methods.
If no timeout is specified in the call to the wait() method, the thread waits indefinitely in the WAITING state until it is notified, interrupted, or awakened spuriously.