it-roy-ru.com

Переход состояния потока Java, ОЖИДАНИЕ БЛОКИРОВАНА или ВЫПОЛНЕНО?

Кажется, существует несоответствие между SO консенсусом и почти каждой диаграммой состояния потоков Java в Интернете; в частности, относительно перехода состояния потока fromWAITING после вызова notify() или notifyAll() ...

  • WAITING никогда переходит непосредственно в RUNNABLE
  • Поток ждет, пока не получит уведомление ... Затем он становится BLOCKED ...
  • Как только этот поток получит уведомление, он не будет работать ... Это ... Заблокированное состояние.

Итак, концепция SO такова: поток переходит из WAITING в BLOCKED после вызова notify() или notifyAll(); диаграмма ниже иллюстрирует этот переход зеленым цветом.

Вопрос

Почему большинство диаграмм состояний в Интернете иллюстрируют переход от WAITING к RUNNABLE, а не BLOCKED? Изображение в красном показывает неправильный переход; я что-то пропустил? 

enter image description here

23
raffian

Любая диаграмма, которая показывает вызов notify, переводящий поток из режима WAITING в RUNNABLE, неверна (или использует невыясненный ярлык). Как только поток пробуждается от notify (или даже от ложного пробуждения), ему необходимо повторно заблокировать монитор объекта, которого он ожидал. Это состояние BLOCKED .

Состояние потока для потока, заблокированного в ожидании блокировки монитора. Тема в заблокированном состоянии ожидает блокировки монитора для ввода синхронизированный блок/метод или повторно введите синхронизированный блок/метод после вызов Object.wait.

Это объясняется в javadoc of Object#notify() :

Пробужденная нить не сможет продолжить работу до текущего поток снимает блокировку этого объекта.

и Object#wait()

Затем поток ожидает, пока не получит право собственности на монитор и возобновляет исполнение.

13
Sotirios Delimanolis

Поток находится вОЖИДАНИИсостояние переходит вБЛОКсостояние, пока не получит монитор путем уведомления и не станетРАБОТОСПОСОБНЫМ

То же самое относится кTIMEDWAITING, оно переходит в состояниеBLOCK, если монитор удерживается каким-либо другим потоком, даже если указанное время прошло .(ваша диаграмма должна быть исправлена)

1
user4768611

Я фокусируюсь на проблеме в последнее время.

в качестве документа Oracle Thread.State говорится, что мы можем использовать LockSupport.park (), чтобы перевести текущий поток в состояние «WAITING» или «TIMED_WAITING». 

поэтому, когда вы используете LockSupport.unpark () , указанный поток вернется к «RUNNABLE» из «WAITING»/«TIMED_WAITING». (Я не уверен, пройдет ли он через состояние «ЗАБЛОКИРОВАНО»)

0
hgfeaon