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

ric*_*chs 5 java concurrency java.util.concurrent

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

public ScheduledFuture<?> schedule(Runnable command, long delay,TimeUnit unit) 
Run Code Online (Sandbox Code Playgroud)

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

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

时间表:1272637682651ms,7858346157228410ns

执行:1272637682667ms,7858386270968425ns

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

因此看起来两个CPU时钟之间的差异为40秒

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

Chr*_*lan 2

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

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

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