Gymterview
junior

Какое из следующих утверждений о потоках неверно?

Рассмотрим четыре утверждения:

  1. Если метод start() вызывается дважды для одного и того же объекта Thread, во время выполнения генерируется исключение.
  2. Порядок, в котором запускались потоки, может не совпадать с порядком их фактического выполнения.
  3. Если метод run() вызывается напрямую для объекта Thread, во время выполнения генерируется исключение.
  4. Если метод sleep() вызывается для потока, во время выполнения синхронизированного кода, блокировка не снимается.

Правильный ответ: утверждение 3 — неверно.

Разбор каждого утверждения:

Утверждение 1 — ВЕРНО. Повторный вызов start() на уже запущенном (или уже завершённом) потоке выбрасывает IllegalThreadStateException. Поток может быть запущен ровно один раз.

Пример
Thread t = new Thread(() -> {});
t.start();
t.start(); // IllegalThreadStateException

Утверждение 2 — ВЕРНО. Порядок фактического выполнения потоков определяется планировщиком ОС и зависит от приоритетов, загрузки процессора и других факторов. Порядок вызова start() не гарантирует порядок выполнения.

Утверждение 3 — НЕВЕРНО. Прямой вызов run() не генерирует исключение. Однако run() выполнится в текущем потоке как обычный метод — новый поток создан не будет. Это частая ошибка начинающих: вместо thread.start() вызывают thread.run().

Пример
Thread t = new Thread(() -> System.out.println(Thread.currentThread().getName()));
t.run();   // Выведет имя ТЕКУЩЕГО потока (main), а не нового
t.start(); // Выведет имя НОВОГО потока (Thread-0)

Утверждение 4 — ВЕРНО. Метод Thread.sleep() переводит поток в состояние TIMED_WAITING, но не освобождает удерживаемые мониторы. Это отличает его от wait(), который освобождает монитор объекта, на котором вызван.

На собеседовании этот вопрос проверяет понимание разницы между start() и run(), а также различие между sleep() и wait() в отношении блокировок.