我正在研究Java程序并使用Timer
个对象每隔几分钟或几小时运行一次任务。这在正常操作中工作正常,但我遇到了Mac上的“睡眠模式”问题(可能在其他操作系统上,但我还没有尝试过)。
请考虑以下代码示例:
//Setup the timer to fire the ping worker (every 3 minutes)
_PingTimer.scheduleAtFixedRate(new TimerTask(){
public void run(){
Program.PingThread = new PingWorker(Settings.Username, Settings.UserHash, true, true);
Program.PingThread.CheckOpenPort = true;
Program.SwingExecutor.execute(Program.PingThread);
}
}, 0, 180000);
在正常操作中,这将以足够的准确度每3分钟发射一次(我并不关心确切的秒或任何事情)。这个问题是在将计算机睡眠几个小时之后,它似乎只是用积压的计时器请求对系统进行BLAST。
似乎在睡眠期间一次性运行所有错过的计时器命中,试图弥补失去的时间。
有没有办法可以阻止这种情况?我尝试使用synchronized
和其他一些线程技术,但这只能确保它们不会同时运行。他们仍然继续一个接一个地运行,直到积压通过。
感谢您提供的任何帮助!
答案 0 :(得分:5)
你看过API了吗?它清楚地说明了以下内容:
在固定费率执行中,每个 执行是相对于 预定的执行时间 初始执行。如果执行是 因任何原因而延迟(例如 垃圾收集或其他背景 活动),两个或多个执行将 快速连续发生“赶上 “从长远来看,频率如此 执行将完全是 指定期间的倒数 (假设系统时钟基础 Object.wait(long)是准确的。)
这是您应该考虑使用ScheduledExecutorService的原因之一。这个link也可能有用。
答案 1 :(得分:2)
使用schedule
代替scheduleAtFixedRate
。