本文介紹了使用ScheduledExecutorService計(jì)劃每月任務(wù)的處理方法,對大家解決問題具有一定的參考價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧!
問題描述
我要將任務(wù)安排在每月的特定日期和特定時(shí)間。每次運(yùn)行之間的間隔可以設(shè)置為1到12個(gè)月。在Java中,可以使用ScheduledExecutorService以固定的時(shí)間間隔調(diào)度任務(wù)。由于一個(gè)月的天數(shù)不是固定的,如何實(shí)現(xiàn)這一點(diǎn)?
提前感謝。
推薦答案
如果您在JavaEE環(huán)境中運(yùn)行,則應(yīng)該使用TimerService或@Schedule注釋。但是,由于您討論的是ScheduledExecutorService,它不允許在Java EE容器中使用,所以我假定您沒有在容器中運(yùn)行。
使用ScheduledExecutorService時(shí),您可以讓任務(wù)本身計(jì)劃下一次迭代:
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版本中,您可以使用日歷執(zhí)行相同的操作:
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);
這篇關(guān)于使用ScheduledExecutorService計(jì)劃每月任務(wù)的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,