java - 使用 ScheduledExecutorService 安排每月任务

标签 java scheduled-tasks

我想将任务安排在每月特定一天的特定时间。每次运行之间的间隔可以设置在 1 到 12 个月之间。在java中,可以使用ScheduledExecutorService以固定的时间间隔调度任务。由于一个月的天数不固定,如何实现?

提前致谢。

最佳答案

如果您在 Java EE 环境中运行,则应该使用 TimerService@Schedule注解。但由于您正在讨论 ScheduledExecutorService,它在 Java EE 容器中不允许使用,因此我假设您没有在其中运行。

当使用 ScheduledExecutorService 时,您可以让任务本身安排下一次迭代:

final ScheduledExecutorService executor = /* ... */ ;

Runnable task = new Runnable() {
    @Override
    public void run() {
        ZonedDateTime now = ZonedDateTime.now();
        long delay = now.until(now.plusMonths(1), ChronoUnit.MILLIS);

        try {
            // ...
        } finally {
            executor.schedule(this, delay, TimeUnit.MILLISECONDS);
        }
    }
};

int dayOfMonth = 5;

ZonedDateTime dateTime = ZonedDateTime.now();
if (dateTime.getDayOfMonth() >= dayOfMonth) {
    dateTime = dateTime.plusMonths(1);
}
dateTime = dateTime.withDayOfMonth(dayOfMonth);
executor.schedule(task,
    ZonedDateTime.now().until(dateTime, ChronoUnit.MILLIS),
    TimeUnit.MILLISECONDS);

在 Java 8 之前的版本中,您可以使用日历来执行相同的操作:

final ScheduledExecutorService executor = /* ... */ ;

Runnable task = new Runnable() {
    @Override
    public void run() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, 1);
        long delay =
            calendar.getTimeInMillis() - System.currentTimeMillis();

        try {
            // ...
        } finally {
            executor.schedule(this, delay, TimeUnit.MILLISECONDS);
        }
    }
};

int dayOfMonth = 5;

Calendar calendar = Calendar.getInstance();
if (calendar.get(Calendar.DAY_OF_MONTH) >= dayOfMonth) {
    calendar.add(Calendar.MONTH, 1);
}
calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
executor.schedule(task,
    calendar.getTimeInMillis() - System.currentTimeMillis(),
    TimeUnit.MILLISECONDS);

关于java - 使用 ScheduledExecutorService 安排每月任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39021895/

相关文章:

java - 如何在java(CVM PhoneME)中实现单实例应用程序管理器?

java - Liferay 中 Alfresco portlet 的 Portlet 暂时不可用消息

java - JTA 事务中使用了哪个超时

powershell - Powershell计划任务报告-将状态从数字更改为单词

java - 使用 ScheduledExecutorService 安排 Applet 启动

java.lang.ClassNotFoundException : org. springframework.ui.ModelMap 错误

来自另一个线程的 JavaFX webengine.executeScript()。

windows - Quartz.NET 与 Windows 计划任务。他们有多不同?

java - 如何使用 Java Timer 和 TimerTask 安排具有开始时间和结束时间的任务

linux - 在 ubuntu 中安排 crontab