Ответ
В Java для планирования периодического выполнения задач (cron-задач) используются следующие основные механизмы:
1. ScheduledExecutorService (рекомендуемый способ):
Часть java.util.concurrent. Позволяет запускать задачи с фиксированной задержкой или периодически, используя пул потоков.
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
// Запуск задачи с фиксированной задержкой
scheduler.schedule(() -> System.out.println("Task executed once"), 5, TimeUnit.SECONDS);
// Запуск задачи периодически с фиксированной частотой
scheduler.scheduleAtFixedRate(() -> System.out.println("Task every 2 seconds"), 0, 2, TimeUnit.SECONDS);
// Запуск задачи периодически с фиксированной задержкой между окончанием одного выполнения и началом следующего
scheduler.scheduleWithFixedDelay(() -> System.out.println("Task with delay"), 0, 1, TimeUnit.SECONDS);
2. Timer и TimerTask (устаревший):
Простой, но менее гибкий. Использует один фоновый поток, и ошибка в одном TimerTask может остановить весь Timer.
3. Специализированные библиотеки и фреймворки:
- Spring Framework: Аннотация
@Scheduled. - Quartz Scheduler: Мощная библиотека для сложного планирования с поддержкой кластеризации и сохранения состояния заданий в БД.
Почему ScheduledExecutorService лучше Timer?
- Использует пул потоков.
- Лучшая обработка исключений (исключение в одной задаче не «ломает» планировщик).
- Более гибкое API (например,
scheduleWithFixedDelay).