2010-04-30 112 views
5

我正在使用ScheduledThreadPoolExecutor对象调度任务。我使用下面的方法:ScheduledThreadPoolExecutor由于CPU时间差异而执行错误的时间

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,113ms)

,所以它看起来像有40秒

两款CPU时钟之间的矛盾如何解决这个问题,我n java代码?不幸的是,这是一台客户机,我无法修改他们的系统。

+0

棘手的一个。也许'java.util.Calendar'会有帮助吗? Calendar.getInstance()等等。 – 2010-04-30 16:00:37

+1

你是否在虚拟机(VMWare,KVM,Virtual PC)上运行此代码?即使在毫秒级别,虚拟化也会对CPU时钟造成严重破坏。 – 2010-05-01 07:17:17

+0

它直接在Windows XP Profession机器上运行。没有虚拟化。 – richs 2010-05-03 13:13:51

回答

2

是的,你说的是ScheduledThreadPoolExecutor使用System.nanoTime()。你也是对的,System.nanoTime()依赖于特定的系统实例。如果您的流程恰好在计划和执行之间迁移,那么您运气不佳。 (我不认为在多CPU系统上的CPU之间迁移会很重要,但也许它确实有影响吗?当然,如果您在虚拟机中运行并且虚拟机在主机之间迁移,那么这一点很重要)。

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

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