Всем добрый день, хочу сделать так, чтобы действие происходило в определённый момент времени, допустим каждый год 01.01 числа звучала какая-нибудь мелодия. Как так сделать, ведь нельзя же просто загнать всё это дело в отдельный поток с бесконечным циклом, ведь вдруг у меня будет выполнятся по 10 таких проверок одновременно, то это вызовет ужасную нагрузку на процессор. Буду рад, если покажете как это делается, может что-то поновее и получше появилось?)
Если вы хотите запускать некоторые события с определенным периодом, то лучше воспользоваться ScheduledExecutorService
как предложил Nofate
. Но если вам необходимо исполнять код в строго определенный день или скажем в строго определенное время, то лучше взять Quartz.
В нем вы сможете создать job
'ы и задать парядок выполнения:
trigger = newTrigger()
.withIdentity("trigger3", "group1")
.withSchedule(dailyAtHourAndMinute(10, 42))
.forJob(myJobKey)
.build();
Данный пример означает, что мы будем запускать нашу задачу ежедневно в 10:42.
Или можно задать более конкретно:
trigger = newTrigger()
.withIdentity("trigger3", "group1")
.withSchedule(cronSchedule("0 0/2 8-17 * * ?"))
.forJob("myJob", "group1")
.build();
Это означает, что наша задача будет исполняться каждые две минуты ежедневно с 8 утра до 5 вечера.
Преимущество данного подхода в том, что мы не зависим от времени старта и перезапуска приложения. Оно у нас строго фиксировано.
Есть очень классный framework, называется apache camel framework. Суть camel в том, что вы можете быстро и удобно запрограммировать некий маршрут с некоей последовательностью действий. Camel поддерживает кучу компонент и протоколов. Очень много готовых решений.
В вашем случае, требуется, например, компонента apache camel timer, которая запускается с заданной периодичностью и активирует маршрут с заданной последовательностью действий.
То есть будет примерно такой код:
from("timer://foo?fixedRate=true&period=60s")
.bean(MyMelodyRunner);
Где каждые 60 секунд будет запускаться ваш некий класс MyMelodyRunner
и запускать bean
-метод, в котором вы и напишите свой код, играющий мелодию и/или рассылающий письма :).
Из коробки в Java есть класс ScheduledExecutorService
, позволяющий запустить задачу через определенное время или с заданной периодичностью.
ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);
// 1 - количество потоков, которые одновременно исполняют задачи
Вы создаете экземпляр задачи:
Runnable task = () -> {
// ваша задача
};
вычисляете отсрочку для задачи от текущего момента, например в миллисекундах, и закидываете задачу в планировщик:
LocalDate date = LocalDate.of(2017, 12, 1);
long delay = LocalDate.now().until(date, ChronoUnit.MILLIS);
pool.schedule(task, delay, TimeUnit.MILLISECONDS);
При этом вы не гоняете процессор вхолостую и все красиво.
Если вы хотите, чтобы запланированные задачи переживали перезапуск вашей программы, нужно будет дополнительно повозиться: хранить список задач во внешнем файле или базе данных, подгружать на старте, вычеркивать выполненные.
Если цель - не повозиться с кодом, а решить задачу, можно посмотреть готовые решения: Quartz, db-scheduler
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Мне нужно добавить в форму авторизации третье поле, но не соображу, как научить Spring Security с ним работатьУ меня пользователи лежат в базе, но кроме...
ПроектНапишите систему, использующую динамические заместители для реализации транзакций: заместитель закрепляет транзакцию, если опосредованный...