Java 定时器和 scheduleAtFixedRate + 系统挂起
Posted
技术标签:
【中文标题】Java 定时器和 scheduleAtFixedRate + 系统挂起【英文标题】:Java Timer and scheduleAtFixedRate + System Suspend 【发布时间】:2011-07-30 21:52:38 【问题描述】:我正在开发一个 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 分钟触发一次(我不关心确切的秒数或其他任何东西)。这个问题是在计算机休眠几个小时左右之后,它似乎只是用积压的计时器请求来破坏系统。
它似乎在一次运行睡眠期间所有错过的计时器,试图弥补失去的时间。
有什么办法可以防止这种情况发生吗?我尝试使用synchronized
和其他一些线程技术,但这只能确保它们不会同时运行。他们仍然继续一个接一个地运行,直到积压过去。
感谢您提供的任何帮助!
【问题讨论】:
帮不上忙 - 只是用 mac,还是一般睡觉? 【参考方案1】:你看过API吗?它明确指出以下内容:
在固定利率执行中,每个 执行是相对于 的预定执行时间 初始执行。如果执行是 因任何原因延迟(例如 垃圾收集或其他背景 活动),两个或更多的执行将 接二连三地“赶上” 向上。”从长远来看, 执行将完全是 指定期间的倒数 (假设系统时钟底层 Object.wait(long) 是准确的)。
这是您应该考虑使用ScheduledExecutorService 的原因之一。这个link 也可能很有用。
【讨论】:
显然我错过了这个重要的注意事项!感谢您对ScheduledExecutorService
的建议。我正在研究这个,今晚我会逐步完成。
@jocull:没问题,让我知道进展如何! :)
好吧,我试了一下,结果似乎是一样的。但是我刚刚意识到我使用的是scheduleAtFixedRate
而不是scheduleWithFixedDelay
。我正在用后者再试一次。
scheduleWithFixedDelay
是票!现在一切似乎都井井有条。再次感谢您!
非常感谢!这也发生在 Windows 上。有一段时间我们想知道为什么从休眠状态唤醒时 CPU 使用率会飙升,直到我们意识到 scheduleWithFixedDelay 会用线程淹没你的 CPU。【参考方案2】:
使用schedule
而不是scheduleAtFixedRate
。
【讨论】:
schedule
本身不会重新排队吗?以上是关于Java 定时器和 scheduleAtFixedRate + 系统挂起的主要内容,如果未能解决你的问题,请参考以下文章
Java 定时器和 scheduleAtFixedRate + 系统挂起