每x次执行一次任务

时间:2013-01-29 08:47:16

标签: java

我正在尝试每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分钟跳转,所以任务运行时效果,但这只是猜测。

3 个答案:

答案 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更现代的方法,并且允许拥有多个工作线程以防万一有许多任务被安排。