Hi there!

Because I'm executing a time critical task every second, I compared several methods to find the best way to ensure that my task is really executed in fixed time steps. After calculating the standard derivation of the error for all methods it seems like using the method scheduledExecutorService.scheduleAtFixedRate() leads to the best results, but I don't have a clue why it is so.

Does anybody know how that method internally works? How does it for example in comparison to a simple sleep() ensure that the referenced task is really executed in fixed time steps?



+1  A: 

You can have a look of the OpenJDK7 implementation of which is the only class implementing the ScheduledExecutorService interface.

However as far as I know there is guarantee in the ScheduledExecutorService about accuracy. So even if your measurments show this to be acurate that may not be the case if you switch to a different platform, vm or jdk .

Because the class internally uses other classes very often, it's very difficult for me to follow it. But I think this might be relevant:I found out that the tasks are put into a PriorityQueue, which probably sorts the tasks by it's priority that means their expected execution time. Therefore it seems like there is really no real-time guarantee.But why is this approach better than a sleep(rate)? Maybe the queue is able to run threads with higher priority than for example the garbage collector to be able to execute the task nearly in real-time?
+2  A: 

A 'normal' Java VM cannot make any hard real-time guarantees about execution times (and as a consequence of that also about scheduling times). If you really need hard real time guarantees you should have a look at a real time VM like Java RTS. Of course you need a real time OS in that case too.

Regarding comparison to Thread.sleep(): the advantage of scheduledExecutorService.scheduleAtFixedRate() compared to a (naive) usage of Thread.sleep() is that it isn't affected by the execution time of the scheduled task. See ScheduledFutureTask.runPeriodic() on how this is implemented.