Как я могу запланировать запуск таймера каждое 10-е число месяца? - PullRequest
1 голос
/ 04 августа 2020

Как я могу запланировать запуск таймера каждое 10-е число месяца?

Заранее большое спасибо

Мой фактический метод:

    @PostConstruct
    public void postConstruct()  throws Exception
    {
        
        final TimerTask task = new TimerTask()
        {
            @Override
            public void run()
            {
                myprocess();
            }
        };
        final Timer timer = new Timer();
        final long delay = 0;
        final long intevalPeriod = 20000;
        // schedules the task to be run in an interval
        timer.scheduleAtFixedRate(task, delay,
                intevalPeriod);
    }

Ответы [ 2 ]

5 голосов
/ 04 августа 2020

Если вы используете Spring, вы можете использовать аннотацию @Scheduled с выражением cron. Просто аннотируйте любой метод publi c в классе bean-компонента следующим образом:

@Scheduled(cron = "0 0 0 10 * *")
public void myprocess() {
    // perform task here
}

Не забудьте включить планирование в контексте вашего приложения. Если вы используете конфигурацию XML:

<task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>
<task:executor id="myExecutor" pool-size="5"/>
<task:scheduler id="myScheduler" pool-size="10"/>

Или, если вы используете класс @Configuration:

@Configuration
@EnableScheduling
public class SpringConfig {
    ...
}

Выражение cron 0 0 0 10 * * разбивается следующим образом:

0  - at the zeroth second of the minute
0  - at the zeroth minute of the hour
0  - at the zeroth hour of the day
10 - on the 10th day of the month
*  - any month
*  - any day of the week

Документация Spring для выражений cron находится здесь: https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/scheduling/support/CronSequenceGenerator.html

Вот ссылка с дополнительной информацией об использовании @Scheduled: https://www.baeldung.com/spring-scheduled-tasks#schedule -a-task-using-cron-expressions

И официальные документы Spring по этому вопросу: https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#scheduling -annotation-support-schedule

1 голос
/ 04 августа 2020

На основе таймера

Если вы ищете ванильное решение, которое придерживается "концепции таймера" , вы можете просто вычислить правильный временной интервал и позволить задаче, когда она готово, снова перепланировать себя с правильным вычисленным временем для следующего выполнения.

См. также Метод вызова в дату / время . Будет выглядеть примерно так:

ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

public static ScheduledFuture<?> scheduleFor(Runnable runnable, ZonedDateTime when) {
    Instant now = Instant.now();
    // Use a different resolution if desired
    long secondsUntil = ChronoUnit.SECONDS.between(now, when.toInstant());

    return scheduler.schedule(runnable, secondsUntil, TimeUnit.of(ChronoUnit.SECONDS));
}

public static ZonedDateTime nextDate() {
    return ZonedDateTime.now().plusMonths(1);
}

И тогда у вас есть задача примерно как

public class MyTask implements Runnable {

    // ...

    @Override
    public void run() {
        // TODO Your stuff ...

        // Reschedule
        scheduleFor(this, nextDate());
    }
}

И сначала запускайте ее как

scheduleFor(task, ZonedDateTime.now().withDayOfMonth(10));

Недостатки

Очевидно, что это решение, поскольку оно основано на таймере , имеет большой недостаток, заключающийся в том, что оно может легко дрейфовать и выходить из синхронизации c. Например, если ваше системное время изменяется или если выполнение задачи занимает так много времени, что вы переноситесь на следующий день. конец.

Если все это не является для вас фактором, он, скорее всего, будет работать так, как задумано.

В противном случае вам, вероятно, следует go для другого, похожего на crontab подхода, где дата периодически проверяется, и как только он соответствует, он выполняет задачу. В отличие от выполнения с фиксированным смещением, как в «выполнить за ... секунд» .

...