Состояния потока

Thread.State содержит ровно шесть состояний:

СостояниеЧто означаетТипичный переход
NEWобъект создан, start() еще не вызванnew Thread(...)
RUNNABLEпоток готов выполняться или выполняетсяпосле start()
BLOCKEDждет входа в synchronized на занятом мониторепопытка захватить монитор
WAITINGждет без тайм-аута действия другого потокаwait(), join(), park()
TIMED_WAITINGждет не дольше заданного времениsleep, timed wait/join/park
TERMINATEDrun() закончен нормально или исключениемфинальное состояние

В перечислении нет отдельных состояний RUNNING, READY и DEAD. JVM объединяет ready и running в RUNNABLE; бытовое «dead» соответствует TERMINATED.

stateDiagram-v2
    [*] --> NEW
    NEW --> RUNNABLE: start()
    RUNNABLE --> BLOCKED: занят monitor
    BLOCKED --> RUNNABLE: monitor получен
    RUNNABLE --> WAITING: wait / join / park
    WAITING --> RUNNABLE: сигнал / завершение / unpark
    RUNNABLE --> TIMED_WAITING: sleep / ожидание с timeout
    TIMED_WAITING --> RUNNABLE: timeout / сигнал
    RUNNABLE --> TERMINATED: run завершен

Важно:

  • yield() не переводит поток в TIMED_WAITING: это лишь подсказка планировщику, поток остается RUNNABLE.
  • interrupt() сам по себе не означает TERMINATED.
  • getState() — мгновенный диагностический снимок. Сразу после чтения состояние уже может измениться.
  • Поток в BLOCKED ждет именно intrinsic monitor. Ожидание Lock, сокета или очереди может отображаться как WAITING/TIMED_WAITING.

На собеседовании

  • Чем BLOCKED отличается от WAITING? Первый ждет входа в занятый synchronized; второй ждет явного события без тайм-аута.
  • Где состояние RUNNING? Оно входит в RUNNABLE.
  • Можно ли повторно запустить TERMINATED? Нет, нужен новый объект Thread.
  • Почему getState() нельзя использовать для координации? Это гоняющийся снимок, а не гарантия.
  • Куда переводит sleep()? В TIMED_WAITING.

См. Thread join, Отличие yield и sleep, Остановка потока.