ScheduledThreadPoolExecutor因CPU时间差异而执行错误的时间

时间:2010-04-30 15:55:28

标签: java concurrency java.util.concurrent

我正在使用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

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

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

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

1 个答案:

答案 0 :(得分:2)

是的,ScheduledThreadPoolExecutor使用System.nanoTime()是对的。而且你也是对的,System.nanoTime()依赖于特定的系统实例。如果您的流程恰好在计划和执行之间迁移,那么您就不走运了。 (我不认为在多CPU系统上的CPU之间进行迁移会很重要,但可能会这样做?当然,如果你在VM中运行并且VM在主机之间迁移,那就很重要了。)

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

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