使用具有不同间隔的计时器执行周期性任务

时间:2010-03-04 03:07:31

标签: java timer ejb puzzle math

我被迫使用计时器执行周期性任务,该计时器以不同的间隔调用,作为我想执行此任务的时间段。

请注意,超时不会100%准确地发生;即,下面的代码中的timeout(javax.ejb.Timer计时器)可能会以100,98,105ms等间隔调用。

所以,我想出了这个,这有点好。但偶尔会在预定的间隔过去之前执行两次任务,或者间隔变得比我想要的长一点。

你有比这更好的想法吗? (代码是简化的伪代码,将在EJB容器中使用)

import javax.annotation.Resource;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerService;

public class TimerBean {
    private static final long TASK_INTERVAL = 1530;
    private static final long TIMEOUT = 100;

    @Resource
    private TimerService timerService;


    public void startTimer() {
        timerService.createTimer(100, TIMEOUT, null);
    }

    @Timeout
    public void timeout(javax.ejb.Timer timer) {
        if(isApproxTime(timer, TASK_INTERVAL)){
            //do stuff
        }
    }

    private boolean isApproxTime(Timer timer, long targetInterval) {
        long modulus = timer.getNextTimeout().getTime() % targetInterval;
        return modulus < TIMEOUT;
    }
}

编辑:我想避免使用ejb.Timer以外的状态,因此保存上次调用的时间不是一种选择。

2 个答案:

答案 0 :(得分:1)

这些确实是奇怪的要求。但是到底是什么。

您可以随时创建计时器吗?如果是这样,请将任务间隔调整为目标间隔过去之前剩余的时间量,或者更小的量。这会漂移,但事件之间的持续时间将大致等于你的目标。

我对你的代码没有一点关于你对事物的控制程度的感觉。例如,是否有允许指定的TIMEOUT窗口?或者是一个由你决定的单一价值,你无论如何都无法控制它?

如果它是后者(完全没有控制权),那么你所做的就是你所能做的就是你所做的一切。我个人会回避HARD关于不在这个bean中存储状态的要求。有问题的国家根本没有持久性或任何其他会导致这个问题的事情。

答案 1 :(得分:0)

Quartz应该为您提供更准确,更可控的计时器