I think it is best to think in terms of underlying synchronization primitives: a java monitor is a mutex, a synchronized block is a region where the mutex is locked upon {
and unlocked upon }
and wait, notify and notifyAll are methods called on a condition variable associated with the mutex.
The important thing to remember is that the mutex can become unlocked within the synchronized block when wait()
is called since wait will unlock the mutex and block until notify or notifyAll is called.
Thus, multiple threads can still be blocked within a synchronized block despite the inference that this is not possible.
Update: Annotated code demonstrating this:
Object lock;
// ...
synchronized (lock) { // Underlying mutex is locked.
// ...
lock.wait(); // Unlocks mutex, blocks until notify, relocks mutex
// ...
} // Underlying mutex unlocked
Once lock.wait()
is called, other threads are free to enter the synchronized block. They too will block until either a lock.notify()
or lock.notifyAll()
wakes them.
wait()
is not something that one thread can do to another. A thread can only block itself by callingo.wait()
. The operations that happen at the beginning and end of asynchronized
block are not available within the Java language itself. They have to be implemented in the JVM, and in most cases, the JVM merely calls out to the operating system. – Handpick