ScheduledExecutorService 在普通 OS/JVM 上的准确性 [英] Accuracy of ScheduledExecutorService on normal OS / JVM

查看:44
本文介绍了ScheduledExecutorService 在普通 OS/JVM 上的准确性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 ScheduledExecutorService.scheduleAtFixedRate 来运行一个日常任务,就像这样:

I use ScheduledExecutorService.scheduleAtFixedRate to run a daily task, like this:

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

(d 是以毫秒为单位的初始延迟).

(d is the initial delay in milliseconds).

执行器由 Executors.newSingleThreadScheduledExecutor() 创建并运行多个任务,但它们都被安排相隔几个小时,最多需要几分钟.

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.

我知道 ScheduledExecutorService 不保证准确性,我需要一个实时操作系统和 JVM 来获得它.不过,这不是我的任务的要求.

I know that ScheduledExecutorService makes no guarantees about accuracy, and I'd need a real-time OS and JVM to get that. That is not a requirement for my task, though.

我注意到,在使用 JDK 1.7.0_03 的 Windows 2003 Server 上,任务每天会减少近 10 秒.每月大约需要 5 分钟,这对我的应用程序来说是可以接受的.无论如何,我可能不得不实施重新调度,因为我希望任务在特定的本地时间运行,因此我必须自己处理 DST.服务运行时间长——半年不重启也不算稀奇.

I noticed that on a Windows 2003 Server, using JDK 1.7.0_03, the task slips by almost 10 seconds per day. That makes about 5 minutes per month, which is acceptable for my application. 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. The service runs for long periods of time - half a year without restart is not that unusual.

不过,我认为对于一个大部分时间处于空闲状态的系统来说,10 秒/天的不准确度相当高,我想知道我是否应该为更糟糕的行为做好准备.

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.

所以我的问题是关于您使用 scheduleAtFixedRate 的体验.10 秒/天正常吗?在其他环境(我们的客户也使用 Linux 和 Solaris 服务器)中,我的准确性会提高还是降低?或者这 10 秒是否表明我们的环境出现问题?

So my question is about your experiences with scheduleAtFixedRate. Are the 10 sec/day normal? Will I get better or worse accuracy in other environments (our customers also use Linux and Solaris servers)? Or are the 10 seconds an indication that something is amiss in our environment?

推荐答案

对于运行时间很长的任务,这并不奇怪.您遇到的另一个问题是它使用了与 NTP 等不同步的 nanoTime().这可能会导致挂钟漂移.

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. 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.

顺便说一句:我会确保您捕获异常甚至抛出的 Throwable.如果您不这样做,您的任务将停止,可能会静默(除非您正在查看返回的 Future 对象)

BTW: I would make sure you catch an exceptions or even Throwable thrown. If you don't your task will stop, possibly silently (unless you are looking at the Future object returned)

我所做的只是作弊.我有一个任务,它每 1 - 10 秒唤醒一次并检查它是否需要运行,如果不需要则返回.如果您没有数千个任务,那么开销通常是微不足道的,而且实现起来要简单得多.

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. The overhead is usually trivial if you don't have thousands of tasks and it's much simpler to implement.

这篇关于ScheduledExecutorService 在普通 OS/JVM 上的准确性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆