В последнем предложении я вижу, что вы не до конца понимаете разницу между synchronized
и wait()
/ notify()
.
По сути, монитор имеет блокировку и состояние .Это почти ортогональные понятия.
Когда поток входит в блок synchronized
, он получает блокировку.Когда поток покидает этот блок, он освобождает блокировку.Только один поток может иметь блокировку на конкретном мониторе.
Когда поток, имеющий блокировку, вызывает wait()
, он снимает блокировку и начинает ожидать своего состояния.Когда поток, имеющий блокировку, вызывает notify()
, один из потоков (все потоки в случае notifyAll()
), ожидающих выполнения условия, становится пригодным для выполнения (и начинает ожидать получения блокировки, так как уведомляющий поток все еще имеет ее).
Итак, ожидая получения блокировки (Thread.State.BLOCKED) и ожидая состояния монитора (Thread.State.WAITING), это разные и независимые состояния.
Это поведение становится более понятным, если вы посмотрите на класс Lock
- он реализует те же примитивы синхронизации, что и блок synchronized
(с некоторыми расширениями), но обеспечивает четкое различие между блокировками и условиями.