ScheduledThreadPoolExecutor的任务调度有多准确

时间:2016-01-18 15:07:26

标签: java concurrency scheduledexecutorservice

我正在阅读ScheduledThreadPoolExecutor JavaDoc并遇到以下情况:

  

延迟任务在启用后立即执行,但没有任何   实时保证何时启用后,   的开始即可。计划完成相同执行时间的任务是   以先进先出(FIFO)提交顺序启用。

所以,如果我写这样的话:

ScheduledExecutorService ses = Executors.newScheduledThreadPool(4); //uses ScheduledThreadPoolExecutor internally
Callable<Integer> c;
//initialize c
ses.schedule(c, 10, TimeUnit.SECONDS);

没有任何保证可调度的执行将在调度后的10秒内启动?据我所知,规范允许它在计划后的一小时内执行(没有任何实时保证,如文档中所述)。

它在实践中如何运作?我应该延长一段时间吗?

1 个答案:

答案 0 :(得分:4)

您的理解是正确的。执行者并不声称自己是具有任何时序保证的实时系统。它唯一能保证的是它不会过早地运行任务。

在实践中,经过良好调整的执行程序的计时非常准确。通常情况下,他们会在我的经验预定时间后10毫秒内开始。如果您的执行者缺乏运行其工作负载的适当资源,那么您唯一一次看到调度被推迟到很远的时间。所以这更像是一个调整问题。

实际上,如果你给你的执行者足够的资源来处理,时间将是非常准确的。

想要使用执行程序的某些事情是将计划用作基于费率的计算的一部分。例如,如果您计划每1秒运行一次任务,并使用该任务每秒计算<somemetric>,而不考虑任务实际运行的时间。

需要注意的另一件事是上下文切换的成本。如果您计划每1ms运行多个任务,则执行程序将无法跟上运行任务上下文切换每个1ms。