我正在使用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代码中解决此问题?不幸的是,这是一台客户端机器,我无法修改他们的系统。
答案 0 :(得分:2)
是的,ScheduledThreadPoolExecutor使用System.nanoTime()是对的。而且你也是对的,System.nanoTime()依赖于特定的系统实例。如果您的流程恰好在计划和执行之间迁移,那么您就不走运了。 (我不认为在多CPU系统上的CPU之间进行迁移会很重要,但可能会这样做?当然,如果你在VM中运行并且VM在主机之间迁移,那就很重要了。)
我认为在这种情况下唯一真正的解决方案是使用ScheduledThreadPoolExecutor之外的其他东西......这不仅仅是改变ScheduledThreadPoolExecutor.now()也不简单。 AbstractQueuedSynchronizer $ ConditionObject.awaitNanos()也使用System.nanoTime()。
我的一个项目使用Quartz进行作业调度,我从未见过您使用该库描述的问题。我不知道实现细节(也许它只是使用System.nanoTime(),但也许不是?)。