Java 每x次执行一项任务

Java 每x次执行一项任务,java,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

我试图每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);
Send看起来是这样的:

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分钟的跳转,因此任务运行时会产生影响,但这只是一个猜测。

为什么不在循环中使用sleep命令或简单地使用sleep命令,让线程睡眠5分钟,然后继续

另一种方法是使用一个

为什么不在循环中使用一个或仅仅是一个sleep命令,让线程睡眠5分钟,然后继续


另一种方法是使用

执行任务所需的时间将延迟计划。发件人:

如果执行因任何原因(如垃圾收集或其他后台活动)而延迟,则后续执行也将延迟

你最好使用它

或者,您可以尝试使用带有循环的简单
线程来重复执行任务。循环中的最后一步可以是睡眠必要的时间,直到您想再次开始任务。假设循环的任何一次迭代都不需要五分钟,这将消除累积延迟

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()
的运行时间或任何系统延迟而累积延迟。我没有查看源代码,但我怀疑这与
计时器中的内容很接近。scheduleAtFixedRate
任务执行所需的时间将延迟计划。发件人:

如果执行因任何原因(如垃圾收集或其他后台活动)而延迟,则后续执行也将延迟

你最好使用它

或者,您可以尝试使用带有循环的简单
线程来重复执行任务。循环中的最后一步可以是睡眠必要的时间,直到您想再次开始任务。假设循环的任何一次迭代都不需要五分钟,这将消除累积延迟

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()
的运行时间或任何系统延迟而累积延迟。我还没看过消息来源,但我怀疑这与
计时器中的功能很接近。scheduleAtFixedRate

我可能会使用比使用
计时器更现代的方法,并允许在计划许多任务的情况下使用多个工作线程。

我可能会使用更现代的方法这种方法比使用
计时器更有效,并且允许在计划许多任务的情况下有多个工作线程。

如果您想在每小时的特定分钟运行,您应该查看Quartz Scheduler“如果您将分钟数减少了%,结果将为0”这是不对的。如果你想在每小时的特定分钟运行,你应该查看Quartz Scheduler“如果你将分钟数百分比设置为0”,这是不对的。一个小问题,线程在执行任务后将休眠,因此如果我在xx:00开始,任务需要1分钟,他休眠5分钟,那么下一个任务将在xx:00生成:06@ImriPersiado-仔细查看如何计算睡眠时间。如果任务耗时一分钟,循环迭代将休眠四分钟,而不是五分钟。一个小问题是,线程在执行任务后将休眠,因此如果我从xx:00开始,任务耗时1分钟,他休眠5分钟,那么下一个任务将在xx:00生成:06@ImriPersiado-仔细查看如何计算睡眠时间。如果任务需要一分钟,循环迭代将休眠四分钟,而不是五分钟。