Переход состояния Java-потока, ОЖИДАНИЕ БЛОКИРОВАТЬ или RUNNABLE?
Похоже, что существует несоответствие между SO-консенсусом и почти каждой диаграммой состояний потоков Java в Интернете; в частности, относительно перехода состояния состояния от WAITING
после вызова notify()
или notifyAll()
...
- WAITING никогда не переходит непосредственно в RUNNABLE
- Поток WAITING, пока он не будет уведомлен... Затем он станет BLOCKED...
- Как только этот поток будет уведомлен, он не будет запущен... Это состояние... заблокированное.
Итак, консенсус по SO: поток переходит из WAITING
в BLOCKED
после вызова notify()
или notifyAll()
; диаграмма ниже иллюстрирует этот переход зеленым цветом.
Вопрос
Почему большинство диаграмм состояний в Интернете иллюстрируют переход от WAITING
в RUNNABLE
, а не BLOCKED
? Изображение красного цвета показывает неправильный переход; я что-то упускаю?
![enter image description here]()
Ответы
Ответ 1
Любая диаграмма, показывающая вызов notify
, приводящий поток от WAITING к RUNNABLE, неверна (или использует неясный ярлык). Как только поток проснулся от notify
(или даже из-под ложного пробуждения), ему нужно переустановить монитор объекта, на котором он ждал. Это состояние BLOCKED
.
Состояние потока для потока, заблокированного в ожидании блокировки монитора. Тема в заблокированном состоянии ожидает блокировки монитора, чтобы войти в синхронизировать блок/метод или повторно ввести синхронизированный блок/метод после вызов Object.wait
.
Это объясняется в javadoc Object#notify()
:
Пробужденная нить не сможет действовать до тех пор, пока текущая thread освобождает блокировку этого объекта.
и Object#wait()
Затем поток ждет, пока он не сможет повторно получить право собственности на монитор и возобновляет выполнение.
Ответ 2
В последнее время я сосредоточен на проблеме.
как документ Oracle Thread.State говорит, что мы можем использовать LockSupport.park(), чтобы поместить текущий поток в состояние "ОЖИДАНИЕ" или "TIMED_WAITING".
поэтому при попытке LockSupport.unpark() указанный поток вернется в "RUNNABLE" из "WAITING" /'TIMED_WAITING', (Я не уверен, пройдет ли он через состояние "BLOCKED" )
Ответ 3
Поток находится в состоянии WAITING в состоянии БЛОК, пока он не получит монитор, уведомив его и не станет RUNNABLE.
То же самое относится к TIMEDWAITING, он переходит в состояние БЛОК, если монитор удерживается каким-либо другим потоком, хотя указанное время прошло (ваша диаграмма должна быть исправлено)