Java 中 ScheduledExecutorService 的时间一致性问题

sha*_*anu 2 java scheduledexecutorservice

我正在尝试使用 ScheduledExecutorService 每 15 分钟调用一次可运行任务。这些任务应该在以下时间每小时运行一次:2nd Minute 10th Second 17th Minute 10th Second 32nd Minute 10th Second 47th Minute 10th Second。

我使用 Calendar 实例计算第一次执行任务的初始延迟,然后使用带有 scheduleAtFixedRate() 的延迟每 15 分钟执行一次任务。这在前几天工作正常,但几天后我可以观察到任务执行中的一些时间偏移。例如,原本应该在 12:02:10 开始的任务在 12:03:45 被调用。我哪里出错了?

public static void main(String[] args) {    
  final ScheduledExecutorService scheduler = Executors
                .newScheduledThreadPool(15);
  Date aDate = new Date();
  Calendar cal = Calendar.getInstance();
  cal.setTime(aDate);
  int currentHour = cal.get(Calendar.HOUR_OF_DAY);
  int currentMins = cal.get(Calendar.MINUTE);
  int currentSecs = cal.get(Calendar.SECOND);
  int unitInSecs;      
  int delayFor15MinTasksInSecs;
  unitInSecs = currentMins * 60 + currentSecs;
  delayFor15MinTasksInSecs = unitInSecs < (3 * 60 - 50 ) ? (3 * 60 - 50 ) - unitInSecs : unitInSecs < (18 * 60 - 50 ) ? (18 * 60 - 50 ) - unitInSecs : unitInSecs < (33 * 60 - 50 ) ? (33 * 60 - 50 ) - unitInSecs : unitInSecs < (48 * 60 - 50 )? (48 * 60 - 50 ) - unitInSecs : (63 *60 - 50 ) - unitInSecs;
  scheduler.scheduleAtFixedRate(new RTPAcquiringTask(10), delayFor15MinTasksInSecs, 15*60, TimeUnit.SECONDS);
}
Run Code Online (Sandbox Code Playgroud)

Ria*_*iaz 5

这个 API 在计时方面并不完美。

来自 Javadoc 的ScheduledExecutorService

但是请注意,由于网络时间同步协议、时钟漂移或其他因素,相对延迟的到期不必与启用任务的当前日期一致。

  • 在设计实时系统时需要考虑很多。空中交通管制是一个很好的模仿模式。以下是一些可能有用的阅读:http://www.oracle.com/technetwork/articles/java/nilsen-realtime-pt2-2264409.html (2认同)