Какое из следующих утверждений о потоках неверно?
Рассмотрим четыре утверждения:
- Если метод
start()вызывается дважды для одного и того же объектаThread, во время выполнения генерируется исключение. - Порядок, в котором запускались потоки, может не совпадать с порядком их фактического выполнения.
- Если метод
run()вызывается напрямую для объектаThread, во время выполнения генерируется исключение. - Если метод
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()в отношении блокировок.