JavaRush/Курсы/Java Core/Здоровый sleep

Здоровый sleep

Открыта

— Привет, Амиго! Билаабо сегодня расскажет тебе о самом интересном методе при работе с нитями – это метод sleep. Метод sleep объявлен как статический метод класса Thread, т.е. он не привязан ни к какому объекту. Цель этого метода, чтобы программа «заснула» на некоторое время. Вот как это работает:

Код Описание
public static void main(String[] args) {
    Thread.sleep(2000);
}
Программа запустится.

Затем замрет на 2 секунды (2 000 миллисекунд)

Затем завершится.

Единственный параметр метода sleep – это время. Время задается в тысячных долях секунды (миллисекундах). Как только нить вызывает этот метод, она засыпает на указанное количество миллисекунд.

— А где это лучше всего использовать?

— Этот метод часто используется в дочерних нитях, когда нужно делать какое-то действие постоянно, но не слишком часто. Смотри пример:

Код Описание
public static void main(String[] args) {
    while (true) {
    Thread.sleep(500);
        System.out.println("Tik");
    }
}
Программа будет работать вечно – условие продолжения цикла никогда не нарушится.

Вот что программа делает в цикле:
а) поспать полсекунды
б) вывести на экран текст «Tik»

Т.е. дважды в секунду будет выполняться некоторое действие.

— Ух ты, теперь это уже интересно.

— Рад, что тебе понравилось, мой друг Амиго!

— А если я хочу, чтобы какое-то действие выполнялась 100 раз в секунду, что нужно делать?

— Если действие должно выполняться 100 раз в секунду, а в секунде 1000 миллисекунд, значит, действие должно выполняться один раз в 10 миллисекунд.

Если твое действие занимает 2 миллисекунды, то нужно добавить к нему паузу длинной 8 миллисекунд. Вместе они будут выполняться как раз за 10 миллисекунд. И за секунду – как раз 100 раз.

Если же твое действие выполняется почти мгновенно, то поставь паузу (sleep) длиной 10 миллисекунд. Тогда в секунду будет тоже около 100 раз.

— Спасибо, Билаабо.

Комментарии (176)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Grigoryvvv
Уровень 28
Expert
1 сентября, 14:21
01.09.2026 / 26 уровень
командир майонеза капитан кетчупа
24 мая, 12:36
👽
Егор Вырва
Уровень 30
5 ноября 2025, 17:46
А как узнать, сколько времени требуется на выполнение моего действия ?
Maxim TerletskySoftware Developer в RutiSoft Corporation
18 октября, 15:43
Способы измерения времени: • System.currentTimeMillis() — возвращает текущее время в миллисекундах (календарное время). Подходит, когда нужно узнать, который сейчас час, или сделать грубый замер. • System.nanoTime() — возвращает время в наносекундах, не привязано к календарю. Используется, когда нужно точно измерить длительность интервала. Для стабильного результата измеряй время несколько раз и бери среднее значение. Пример:
public class ActionTimer {

    public static void main(String[] args) {
        // Прогрев JVM: первые вызовы медленнее из-за JIT-компиляции
        for (int i = 0; i < 1000; i++) {
            doSomething();
        }

        long totalNanos = 0;
        int runs = 20; // больше прогонов → стабильнее среднее

        for (int i = 0; i < runs; i++) {
            long start = System.nanoTime();
            doSomething();
            totalNanos += System.nanoTime() - start;
        }

        double avgMillis = (double) totalNanos / runs / 1_000_000;
        System.out.printf("В среднем: ~%.3f мс%n", avgMillis);
    }

    private static void doSomething() {
        for (int i = 0; i < 1000; i++) {
            System.out.println(i);
        }
    }
}
Советы: • Прогрей JVM перед замером или отбрось первый замер — первые вызовы медленнее из-за JIT-компиляции. Сделай несколько «холостых» прогонов до основного замера; если вариант с прогревом не устраивает — просто не учитывай результат первой итерации. • Увеличь число прогонов — для стабильного результата выполняй 10–20 прогонов: чем быстрее выполняется действие, тем больше прогонов требуется, чтобы случайные колебания сгладились. • Учитывай погрешность измерения — на результат влияют загрузка CPU, работа сборщика мусора (GC) и другие фоновые процессы, поэтому замер следует рассматривать как ориентировочную оценку порядка величины, а не как абсолютно точное значение.
Maxim TerletskySoftware Developer в RutiSoft Corporation
18 октября, 16:14
Как быть с полученным результатом? Допустим, после 20 замеров из примера получили это:
В среднем: ~9,713 мс
Тогда можно сделать вывод: одно выполнение doSomething() занимает в среднем 9,713 мс. Это значит, что за 1 секунду (1000 мс) действие успевает выполниться 102 раза:
1000 мс / 9,713 мс = 102,955 ≈ 102 раза (округление в меньшую сторону)
Итог: при времени выполнения ~9,713 мс действие укладывается в цель 100 раз в секунду:
9,713 мс < 10 мс = 1000 мс / 100 раз
Тем не менее, запас времени крошечный — любое колебание может сделать sleepTime отрицательным. Существует три решения подобной проблемы: • ускорить само действие — задача оптимизации. Например, сократить число обращений к консоли: буферизовать вывод или собрать строки в StringBuilder и вывести их одним вызовом в конце, вместо 1000 отдельных System.out.println; • вынести тяжёлую работу в отдельный поток — задача многопоточности. Например, тикер каждые 10 мс кладёт задачу в очередь и сразу продолжает, а отдельный поток-исполнитель разбирает очередь и выполняет вывод; • снизить требуемую частоту до реально достижимой — задача грамотного целеполагания. Например, вместо 100 раз в секунду поставить цель 50 раз в секунду (период 20 мс вместо 10 мс) — тогда время выполнения ~9,713 мс с хорошим запасом укладывается в период.
invoker main
Уровень 42
30 сентября 2025, 14:44
билаабо
Vulki
Уровень 53
22 сентября 2025, 06:32
👽
Anonymous #3585174
Уровень 33
21 августа 2025, 13:07
like
dustik
Уровень 29
30 июля 2025, 16:00
👽
26 июня 2025, 13:05
👽
SliNe
Уровень 43
16 июня 2025, 21:18
👽
Ioanna Polyak
Уровень 51
13 июня 2025, 12:59
👽