使用ScheduledExecutorService安排每月任务

时间:2016-08-18 15:18:37

标签: java scheduled-tasks

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

提前致谢。

2 个答案:

答案 0 :(得分:2)

如果您在Java EE环境中运行,则应使用TimerService@Schedule注释。但是,由于您正在讨论在Java EE容器中不允许使用的ScheduledExecutorService,我假设您没有在一个容器中运行。

使用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);

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

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);

答案 1 :(得分:0)

由于你想要长时间执行一次的东西,你需要一些可靠的东西。

看一下Quartz:

http://www.quartz-scheduler.org/documentation/quartz-2.x/cookbook/MonthlyTrigger.html