我正在尝试每5分钟执行一次任务。 任务需要从:xx:00,xx:05,xx:10,xx:15开始,依此类推,如果时间是xx:37,任务将以xx:40开始。
我使用以下代码来执行此操作:
Date d1 = new Date();
d1.setMinutes(d1.getMinutes() + 5 - d1.getMinutes()%5);
d1.setSeconds(0);
this.timer.schedule(new Send(), d1, TEN_MINUTES/2);
发送看起来像这样:
class Send extends TimerTask
{
public void run()
{
if(SomeCondition)
{
Timestamp ts1 = new Timestamp(new java.util.Date().getTime());
SendToDB(ts1);
}
}
}
因此,结果应该是记录,如果您将分钟的百分比结果为0。 但我记录的时间是:
* 05:35:00 * 07:44:40 * 07:54:40 * 09:05:31 * 09:50:00
正如你所看到的那样,第一项任务完全开始,但后来出了问题。
我的猜测是,任务计算完上一个任务完成后的5分钟跳转,所以任务运行时效果,但这只是猜测。
答案 0 :(得分:2)
任务执行所需的时间将延迟计划。来自the docs for schedule
:
如果执行因任何原因(例如垃圾收集或其他后台活动)而延迟,则后续执行也会延迟。
最好使用scheduleAtFixedRate
。
或者,您可以尝试使用带有循环的简单Thread
来重复执行任务。循环的最后一步可以是睡眠所需的时间,直到您想再次启动任务。假设循环的任何一次迭代都不需要五分钟,这将消除累积延迟。
public void run() {
long start = System.currentTimeMillis();
while (shouldRun()) {
doTask();
long next = start + FIVE_MINUTES;
try {
Thread.sleep(next - System.currentTimeMillis());
start = next;
} catch (InterruptedException e) {
. . .
}
}
}
这将在下一个五分钟间隔开始每次迭代,并且由于doTask()
的运行时间或任何系统延迟而不会累积延迟。我没有查看来源,但我怀疑这与Timer.scheduleAtFixedRate
中的内容很接近。
答案 1 :(得分:1)
为什么不在循环中使用Task scheduler或简单的睡眠命令让线程休眠5分钟然后继续。
另一种方法是使用Timer class
答案 2 :(得分:0)
我可能会使用ScheduleExecutorService.scheduleAtFixedRate这是一种比使用Timer
更现代的方法,并且允许拥有多个工作线程以防万一有许多任务被安排。