ScheduledThreadPoolExecutor 的任务调度有多准确

How accurate is the task scheduling of a ScheduledThreadPoolExecutor

我在阅读 ScheduledThreadPoolExecutor JavaDoc 时发现了以下内容:

Delayed tasks execute no sooner than they are enabled, but without any real-time guarantees about when, after they are enabled, they will commence. Tasks scheduled for exactly the same execution time are enabled in first-in-first-out (FIFO) order of submission.

所以,如果我这样写:

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

不能保证可调用对象会在调度后 10 秒内开始执行?据我所知,规范允许它甚至在计划后的一小时内执行(没有任何实时保证,如文档中所述)。

它在实践中是如何运作的?我应该排除一些非常长的延迟吗?

您的理解是正确的。 Executor 并未声称自己是一个具有任何时间保证的 real-time 系统。它唯一能保证的是它不会 运行 任务过早。

实际上,well-tuned 执行器的计时非常准确。根据我的经验,它们通常在预定时间后 10 毫秒内开始。如果您的执行器缺少适当的资源来 运行 它的工作量,您唯一会看到调度被推迟得很远。所以这更像是一个调整问题。

实际上,如果您为 Executor 提供足够的资源来使用,时间安排会非常准确。


不想使用执行器做的一些事情是将调度用作rate-based计算的一部分。例如,如果您将任务安排为每 1 秒 运行,并使用它来计算每秒 <somemetric>,而不考虑任务实际 运行 的时间。

另一件需要注意的事情是上下文切换的成本。如果您每 1 毫秒将多个任务安排到 运行,执行器将无法跟上 运行 宁您的任务 上下文切换每个人 1 毫秒。