Автор оригинала: Jacob Stopak.
1. введение
Относительно часто программы Java добавляют задержку или паузу в свою работу. Это может быть полезно для ускорения выполнения задачи или для приостановки выполнения до завершения другой задачи.
В этом руководстве будут описаны два способа реализации задержек в Java.
2. Подход, Основанный На Потоках
Когда запускается программа Java, она порождает процесс , который выполняется на хост-машине. Этот процесс содержит по крайней мере один поток – основной поток – в котором выполняется программа. Кроме того, Java позволяет многопоточность , что позволяет приложениям создавать новые потоки, которые выполняются параллельно или асинхронно с основным потоком.
2.1. Использование Thread.sleep
Быстрый и грязный способ приостановки в Java-это указать текущему потоку, чтобы он спал в течение определенного периода времени. Это можно сделать с помощью Thread.sleep(миллисекунды) :
try { Thread.sleep(secondsToSleep * 1000); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); }
Рекомендуется обернуть метод sleep в блок try/catch на случай, если другой поток прерывает спящий поток. В этом случае мы перехватываем исключение InterruptedException и явно прерываем текущий поток, чтобы его можно было перехватить позже и обработать. Это более важно в многопоточной программе, но все же хорошая практика в однопоточной программе на случай, если мы добавим другие потоки позже.
2.2. Использование TimeUnit.sleep
Для лучшей читаемости мы можем использовать TimeUnit.XXX.sleep(y) , Где XXX – единица времени для сна ( СЕКУНДЫ , МИНУТЫ и т. Д.), А y – номер этой единицы для сна. Это использует Thread.sleep за кулисами. Вот пример синтаксиса Единицы времени :
try { TimeUnit.SECONDS.sleep(secondsToSleep); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); }
Однако есть некоторые недостатки в использовании этих методов на основе потоков :
- Время сна не совсем точно, особенно при использовании меньших временных приращений, таких как миллисекунды и наносекунды
- При использовании внутри циклов сон будет немного смещаться между итерациями цикла из-за выполнения другого кода, поэтому время выполнения может стать неточным после многих итераций
3. Подход, Основанный На ExecutorService
Java предоставляет интерфейс ScheduledExecutorService, который является более надежным и точным решением. Этот интерфейс может запланировать выполнение кода один раз после указанной задержки или через фиксированные интервалы времени.
Чтобы запустить фрагмент кода один раз после задержки, мы можем использовать метод schedule :
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); executorService.schedule(Classname::someTask, delayInSeconds, TimeUnit.SECONDS);
Имя класса :: некоторая задача часть, в которой мы указываем метод, который будет выполняться после задержки:
- некоторая задача – это имя метода, который мы хотим выполнить
- Имя класса – это имя класса, содержащего ту же задачу метод
Для выполнения задачи с фиксированными интервалами времени мы можем использовать метод scheduleAtFixedRate :
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); executorService.scheduleAtFixedRate(Classname::someTask, 0, delayInSeconds, TimeUnit.SECONDS);
Это приведет к многократному вызову метода некоторой задачи , делая паузу для задержки В секундах между каждым вызовом.
Кроме того, позволяя больше вариантов синхронизации, метод ScheduledExecutorService дает более точные временные интервалы, так как он предотвращает проблемы с дрейфом.
4. Заключение
В этой статье мы обсудили два метода создания задержек в программах Java.
Полный код этой статьи можно найти на Github . Это проект на основе Maven, поэтому его должно быть легко импортировать и запускать как есть.