简体   繁体   English

正常OS / JVM上ScheduledExecutorService的准确性

[英]Accuracy of ScheduledExecutorService on normal OS / JVM

I use ScheduledExecutorService.scheduleAtFixedRate to run a daily task, like this: 我使用ScheduledExecutorService.scheduleAtFixedRate来运行每日任务,如下所示:

executor.scheduleAtFixedRate(task, d, 24L * 3600 * 1000, TimeUnit.MILLISECONDS);

( d is the initial delay in milliseconds). d是以毫秒为单位的初始延迟)。

The executor is created by Executors.newSingleThreadScheduledExecutor() and runs multiple tasks, but they are all scheduled a few hours apart, and take at most a few minutes. 执行程序由Executors.newSingleThreadScheduledExecutor()创建并运行多个任务,但它们都是相隔几个小时安排的,最多需要几分钟。

I know that ScheduledExecutorService makes no guarantees about accuracy, and I'd need a real-time OS and JVM to get that. 我知道ScheduledExecutorService不保证准确性,我需要一个实时操作系统和JVM来实现这一点。 That is not a requirement for my task, though. 但是,这不是我的任务的要求。

I noticed that on a Windows 2003 Server, using JDK 1.7.0_03, the task slips by almost 10 seconds per day. 我注意到在Windows 2003 Server上,使用JDK 1.7.0_03,任务每天下滑几乎10秒。 That makes about 5 minutes per month, which is acceptable for my application. 每个月大约需要5分钟,这对我的申请来说是可以接受的。 I'll probably have to implement re-scheduling anyway, because I want the task to run at a specific local time, and so I'll have to take care of DST myself. 我可能不得不实施重新安排,因为我希望任务在特定的当地时间运行,所以我必须自己处理DST。 The service runs for long periods of time - half a year without restart is not that unusual. 该服务运行很长一段时间 - 没有重启的半年也不是那么罕见。

Still, I think that an inaccuracy of 10 sec/day is rather high for a mostly idle system, and I wonder if I should be prepared for even worse behavior. 尽管如此,我认为对于大多数闲置的系统而言,10秒/天的不准确度相当高,我想知道我是否应该为更糟糕的行为做好准备。

So my question is about your experiences with scheduleAtFixedRate . 所以我的问题是关于scheduleAtFixedRate的经验。 Are the 10 sec/day normal? 10秒/天正常吗? Will I get better or worse accuracy in other environments (our customers also use Linux and Solaris servers)? 我会在其他环境中获得更好或更差的准确度(我们的客户也使用Linux和Solaris服务器)吗? Or are the 10 seconds an indication that something is amiss in our environment? 或者10秒是否表明我们的环境出现问题?

For a very long running task, it is not too surprising. 对于一个长期运行的任务,它并不太令人惊讶。 Another problem you have is that it uses nanoTime() which is not synchronized with NTP or the like. 您遇到的另一个问题是它使用的nanoTime()与NTP等不同步。 This can result in drift with the wall clock. 这可能导致挂钟漂移。

One way to avoid this is to schedule repeatedly as you suggest. 避免这种情况的一种方法是按照您的建议重复安排。 The repeating tasks actually reschedule themselves (which is why they cannot throws an exception, see below) You can have a one shot task which reschedules itself at the end, using the wall clock time and taking into account day list savings. 重复任务实际上是重新安排自己(这就是为什么他们不能抛出异常,见下文)你可以使用一次性任务,在最后重新安排自己,使用挂钟时间并考虑到日期列表节省。

BTW: I would make sure you catch an exceptions or even Throwable thrown. 顺便说一句:我会确保你抓到一个例外,甚至扔掉了Throwable。 If you don't your task will stop, possibly silently (unless you are looking at the Future object returned) 如果你不这样做,你的任务就会停止,可能是静默的(除非你正在查看返回的Future对象)

What I do is cheat a little. 我做的是作弊。 I have a task which wakes every 1 - 10 seconds and checks if it needs to run and if not returns. 我有一个任务,每1到10秒唤醒一次,检查是否需要运行,如果没有则返回。 The overhead is usually trivial if you don't have thousands of tasks and it's much simpler to implement. 如果您没有数千个任务并且实现起来要简单得多,那么开销通常是微不足道的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM