简体   繁体   中英

Performing a task every x time

I'm trying to perform a task every 5 minute. The task need to start from: xx:00, xx:05, xx:10, xx:15 and so on so if the time is xx:37 the task will start in xx:40.

I'm used the following code to do that:

    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 looks like that:

class Send extends TimerTask
{
    public void run()
    {
        if(SomeCondition)
                    {
                            Timestamp ts1 = new Timestamp(new java.util.Date().getTime());
                            SendToDB(ts1);
                    }
    }
}

So the result should be records that if you % the minutes the result would be 0. But the records time I have is:

*05:35:00 *07:44:40 *07:54:40 *09:05:31 *09:50:00

As you can see the first task start perfectly but then something went wrong.

My guess is that the task calculateds the 5 minute jump after the previous task is finished so the task run time effects, but it's just a guess.

The time a task takes to execute will delay the schedule. From the docs for schedule :

If an execution is delayed for any reason (such as garbage collection or other background activity), subsequent executions will be delayed as well.

You will be better off using scheduleAtFixedRate .

Alternatively, you might try using a simple Thread with a loop to repeatedly perform the task. The last step in the loop can be to sleep the necessary time until you want to start the task again. Assuming that no one iteration of the loop takes five minutes, this will eliminate cumulative delays.

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) {
            . . .
        }
    }
}

This will start each iteration at the next five-minute interval and will not accumulate delays due to the running time of doTask() or any system delays. I haven't looked at the sources, but I suspect that this is close to what's in Timer.scheduleAtFixedRate .

Why dont you use a Task scheduler or simply a sleep command in a loop which lets the thread sleep for 5 minutes then continue.

An alternative would be to use a Timer class

我可能会使用ScheduleExecutorService.scheduleAtFixedRate ,这是一种比使用Timer更现代的方法,并且在安排了许多任务的情况下,允许使用多个工作线程。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM