5

我正在使用 ScheduledThreadPoolExecutor 对象安排任务。我使用以下方法:

public ScheduledFuture<?> schedule(Runnable command, long delay,TimeUnit unit) 

并将延迟设置为 30 秒(延迟 = 30,000 和单位=TimeUnit.MILLISECONDS)。有时我的任务会立即发生,有时需要 70 秒。

我相信 ScheduledThreadPoolExecutor 使用 CPU 特定的时钟。当我运行比较 System.currentTimeMillis()、System.nanoTime() [这是 CPU 特定的] 的测试时,我看到以下内容

时间表:1272637682651ms,7858346157228410ns

执行:1272637682667ms,7858386270968425ns

差异是 16 毫秒,但 4011374001ns(或 40,113 毫秒)

所以看起来两个40秒的CPU时钟之间存在差异

我如何在java代码中解决这个问题?不幸的是,这是一台客户端机器,我无法修改他们的系统。

4

1 回答 1

2

是的,ScheduledThreadPoolExecutor 使用 System.nanoTime() 是对的。而且您也说对了 System.nanoTime() 取决于特定的系统实例。如果您的流程碰巧在计划和执行之间迁移,那么您就不走运了。(我认为在多 CPU 系统上的 CPU 之间迁移并不重要,但也许确实如此?当然,如果您在 VM 中运行并且 VM 在主机之间迁移,这很重要)。

我认为在这种情况下唯一真正的解决方案是使用 ScheduledThreadPoolExecutor 以外的东西......这也不是仅仅改变 ScheduledThreadPoolExecutor.now() 那样简单。AbstractQueuedSynchronizer$ConditionObject.awaitNanos() 也使用 System.nanoTime()。

我的一个项目使用Quartz进行作业调度,我从未见过你用那个库描述的问题。我不知道实现细节(也许它也只使用 System.nanoTime(),但也许不是?)。

于 2010-05-02T08:15:19.127 回答