Какие состояния (state) может иметь поток (Thread) в Java?

«Какие состояния (state) может иметь поток (Thread) в Java?» — вопрос из категории Other, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Поток в Java за время своего жизненного цикла проходит через шесть состояний, определённых в перечислении Thread.State.

Диаграмма состояний потока:

NEW → RUNNABLE → (BLOCKED, WAITING, TIMED_WAITING) → TERMINATED

Описание каждого состояния:

  1. NEW: Поток создан (конструктор Thread вызван), но метод start() ещё не вызван. Поток не является «живым».

  2. RUNNABLE: Поток выполняется или готов к выполнию. Он находится в пуле потоков JVM и ожидает выделения процессорного времени от планировщика ОС. Это состояние объединяет понятия «готов» и «работает».

  3. BLOCKED: Поток заблокирован и ожидает получения монитора (входа в synchronized-секцию или метод), который в данный момент удерживается другим потоком.

  4. WAITING: Поток перешёл в это состояние, вызвав один из методов без таймаута:

    • Object.wait() (без параметров)
    • Thread.join() (без параметров)
    • LockSupport.park() Поток будет находиться в этом состоянии, пока другой поток не вызовет соответствующий сигнализирующий метод (например, notify()/notifyAll() для wait()).
  5. TIMED_WAITING: Поток ожидает в течение заданного промежутка времени. Это состояние возникает при вызове:

    • Thread.sleep(long millis)
    • Object.wait(long timeout)
    • Thread.join(long millis)
    • LockSupport.parkNanos() / parkUntil()
  6. TERMINATED: Поток завершил выполнение своего метода run(). Возврат в это состояние невозможен.

Пример проверки состояния:

public class ThreadStateDemo {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            try {
                Thread.sleep(2000); // Переход в TIMED_WAITING
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        System.out.println("Before start: " + thread.getState()); // NEW
        thread.start();
        System.out.println("After start: " + thread.getState());  // RUNNABLE (или TIMED_WAITING)
        Thread.sleep(100);
        System.out.println("During sleep: " + thread.getState()); // TIMED_WAITING
        thread.join(); // Ожидаем завершения потока
        System.out.println("After join: " + thread.getState());   // TERMINATED
    }
}