我有一个简单的计时器,可以调用每分钟进行后台处理的方法。它被称为:
EmailSender singletonSender = new EmailSender(cog);
timer.scheduleAtFixedRate(singletonSender, 60000, 60000);
每收到一个活动,检查是否有任何理由发送电子邮件,发送电子邮件,然后就完成了。
这一切都假设系统已启动并正在运行,并且存在可用的CPU周期。如果计算机坐在那里什么都不做,并且处理不花时间,那么很容易理解。但是,我无法找到有关计算机过度繁忙或进入睡眠/混沌模式时的行为方式的文档。
如果计算机处于睡眠状态会怎样?
在检查了许多令人困惑的日志后,我终于进行了测试。它打印出日志声明和当前时间。我让计算机在7:30(大约)睡觉,10分钟后(大约)醒来。这是日志跟踪:
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:24:28
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:25:28
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:26:28
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:27:28
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:28:28
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:29:28
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:30:28
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:31:28
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:40:09
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:40:09
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:40:09
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:40:09
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:40:09
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:40:09
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:40:09
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:40:09
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:40:28
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:41:28
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:42:28
似乎发送了一堆"追赶"事件。换句话说,就好像它们在睡眠时堆积在计算机中一样,然后一旦机器重新启动它们就会全部溢出。好像所有的事件都是生成的,但由于无法提供这些事件而被阻止,最后,当计算机启动时,所有事件都会溢出。
这是否按照这种方式设计?显然,这会对您设计系统的方式产生影响。如果您预计每天有1440个事件,那么您最终将获得1440个事件,这是合乎逻辑的。但是,如果您只是进行后台处理,并且每个调用都会完成所有等待的后台操作,那么这些额外的调用就没那么无意义了。您将需要设计方法来快速处理这些额外的呼叫。
如果响应通话需要一分多钟时间怎么办?
鉴于上述证据,似乎如果计算机变得非常繁忙,您的活动可能会延迟发送,但您仍然可以获得所有活动。因此,如果事件处理时间超过一分钟,问题是:您能确定事件不会到达不同的线程吗?换句话说:您是否确信在最后一次调用完成之前永远不会调用您的处理程序。 Timer机制试图隐藏有关您调用的线程的详细信息,并且假设所有调用都在单个线程上进行似乎是合理的,但是,我再次寻找有关此的明确文档。
我想知道的是:这是严格定义的吗?或者只是当前版本实现方式的工件?
答案 0 :(得分:4)
至少Timer#scheduleAtFixedRate
的Javadocs建议您观察到的内容:
在固定速率执行中,每次执行都是相对于初始执行的预定执行时间进行调度的。 如果由于任何原因(例如垃圾收集或其他后台活动)导致执行被延迟,则会快速连续执行两次或更多次执行以“赶上”。从长远来看,执行频率将完全是指定时间段的倒数(假设Object.wait(long)下的系统时钟是准确的)。