虽然我使用的是fixedRate方法而不是简单的计划,但这确实可以确保没有任何后台活动或垃圾收集可以解决我的时间问题?延迟是否足够长,以使后续运行错过我给出的整个窗口? (上午8:00到早上8:05)。我已经通过更改操作系统时间来测试执行情况,但它可以工作,但这是第一次使用调度和时序逻辑。
//1 day
static final long timeDelay = 864000000;
public static void main(String[] args) {
Timer timer = new Timer();
TimerTask startBegin = new TimerTask() {
@Override
public void run() {
Calendar cal = Calendar.getInstance();
int month = cal.get(Calendar.MONTH); // 0 to 11
int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH);
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
int hour = cal.get(Calendar.HOUR_OF_DAY);
int minute = cal.get(Calendar.MINUTE);
// March, June, Sept, Dec, First Tues at 8 a.m
if(((month == 2)||(month == 5)||(month == 8)||(month == 11)) && (dayOfMonth <7) && (hour == 8) && (minute >= 0 && minute <5)) {
begin();
}
}
};
timer.scheduleAtFixedRate(startBegin, 0, timeDelay);
}
答案 0 :(得分:1)
ScheduledExecutorService将尽最大努力在指定的时间运行您的程序 - 但是由于先发制人的多线程的变幻无常,以及它运行的操作系统和硬件的限制,它是有限的。
有些东西被称为“实时操作系统”,旨在解决这个问题,但是对于大多数情况,标准的Java行为将“足够好”。实际错误很小,scheduleAtFixedRate
没有累积错误等等。
答案 1 :(得分:0)
永远无法保证在特定时间窗口内执行,就像无法保证网络连接一样。您可以自行决定在您的环境中是否存在严重风险以及如何应对 - 无论是让时间滑动,还是跳过它并在下一个窗口再试一次,或者其他什么。
答案 2 :(得分:0)
根据javadoc,计时器是单个后台线程。垃圾收集可能会干扰,繁忙的CPU也会干扰。
如果您需要更可靠的计时,则需要一个支持它的实时操作系统。
答案 3 :(得分:0)
我不会将这种不经常执行的任务委托给java.util.Timer
甚至是ScheduledExecutorService
......
我宁愿使用像Quartz之类的库,也可以在Linux或Windows任务计划程序上设置像cron这样的外部作业调度程序,以便每季度触发一次清理工作。这将导致您的工作少得多,因为所有杂乱的边缘情况都将由调度程序/库处理。包括机器在半夜意外重启电源等情况。然后您可以自由地完成更高效的任务。