Gymterview
junior

Что значит усыпить поток?

«Усыпить» поток означает приостановить его выполнение на заданный промежуток времени с помощью статического метода Thread.sleep(). Поток переходит из состояния RUNNABLE в состояние TIMED_WAITING и не потребляет процессорное время до истечения указанного интервала.

Сигнатуры метода

Пример
// Пауза на указанное число миллисекунд
public static void sleep(long millis) throws InterruptedException;

// Пауза с точностью до наносекунд
public static void sleep(long millis, int nanos) throws InterruptedException;

// Java 19+ — пауза с использованием Duration
public static void sleep(Duration duration) throws InterruptedException;

Ключевые особенности

Аспект Описание
Монитор Поток не освобождает захваченные мониторы во время сна
Прерывание Если во время сна вызван interrupt(), поток проснётся досрочно и выбросит InterruptedException. Флаг прерывания при этом сбрасывается
Точность Реальная пауза может быть длиннее заданной (зависит от загрузки системы и гранулярности таймера ОС). На Windows гранулярность по умолчанию ~15.6 мс
sleep(0) Отдаёт остаток текущего кванта времени планировщику, аналогично Thread.yield(), но с некоторыми отличиями

Пример

Пример: усыпление с обработкой прерывания
public class SleepDemo {
    public static void main(String[] args) {
        Thread worker = new Thread(() -> {
            try {
                System.out.println("Поток засыпает на 5 секунд...");
                Thread.sleep(5000);
                System.out.println("Поток проснулся!");
            } catch (InterruptedException e) {
                System.out.println("Поток разбужен досрочно прерыванием!");
                // Хорошая практика: восстановить флаг прерывания
                Thread.currentThread().interrupt();
            }
        });
        worker.start();

        // Через 2 секунды прерываем спящий поток
        try { Thread.sleep(2000); } catch (InterruptedException e) { }
        worker.interrupt(); // Поток проснётся досрочно
    }
}

Отличие от wait()

Характеристика Thread.sleep() Object.wait()
Освобождает монитор Нет Да
Требует synchronized Нет Да
Пробуждение Только по таймеру или interrupt() По notify()/notifyAll(), таймеру или interrupt()
Назначение Пауза на фиксированное время Ожидание условия от другого потока

Аналогия из жизни. Thread.sleep() – это будильник: вы засыпаете и просыпаетесь через заданное время. Но если вас разбудят раньше (прерывание), вы проснётесь, но будете раздражены (InterruptedException). При этом, если вы заснули, держа ключ от комнаты (монитор), – ключ остаётся у вас, и никто не может войти.

На собеседовании. Два обязательных момента: (1) sleep() не освобождает монитор – это классический подвопрос; (2) InterruptedException – не игнорируйте его, а обрабатывайте или восстанавливайте флаг прерывания через Thread.currentThread().interrupt(). Также можно упомянуть TimeUnit.SECONDS.sleep(5) как более читаемую альтернативу Thread.sleep(5000).