24

I'm studying computer hardware where we learn that using a hardware timer gets more accurate results than a software delay. I've written a software delay in assembly for 1 millisecond and I can start a process that repeats every millisecod using this delay and with a counter do something else every 100th millisecond, and this technique would be less accurate than using a hardware timer that I got builtin with my hardware that I'm going to use now.

So I wonder how accurate is the timing that is builtin with Java? We have System.currentTimeMillis and Thread.sleep and these might not use hardware timers, so how accurate are these builtin Java methods compared to a hardware timer?

Niklas Rosencrantz
  • 25,640
  • 75
  • 229
  • 424
  • 3
    I believe the `sleep` time functions work as "Sleep atleast for", especially since this would have to interplay with CPU scheduling etc – Karthik T Sep 11 '13 at 08:55
  • I would imagine that your machine is being DOS'd then it would not be very accurate at all – Scary Wombat Sep 11 '13 at 08:55
  • 2
    Incredibly inaccurate. You have to deal with the inconsistencies of the OS process scheduler, the time spent context switching, the Java VM, etc. – Jonathon Reinhart Sep 11 '13 at 08:58
  • 1
    Well documentation is silent on its accuracy- it talks a lot about accuracy for System.nanoTime- my personal experience has been that passed milliseconds are only a lower bound on sleep time and thread sometime sleep much longer, though not often. – mawia Sep 11 '13 at 09:04
  • 1
    I used to compare the same Thread.sleep based timer in 2 computers and the older one was a little bit slower, after few minutes it was like 2 seconds behind. So.. I wouldn't rely on it as a 100% exact timer, but more like a "sleep around this time if you are stable". – porfiriopartida Sep 11 '13 at 09:06
  • @KarthikT So it really is not a good idea to use e.g. `sleep(5)` in an update method that repaints a canvas or is that example something that can be done in a less than exact way compared to other functions that must be realtime? – Niklas Rosencrantz Sep 11 '13 at 09:07
  • 3
    @909Niklas I think the redrawing may be an example of something that can be done in a less than exact way. If you use `sleep` for limiting the number of frames per second I don't think it will matter much if sometimes it is off. Though it may become an issue if you need synchronize the repaint with something else (Active shutter 3D system maybe?). – Viktor Seifert Sep 11 '13 at 09:44

3 Answers3

17

Thread.sleep() is inaccurate. How inaccurate depends on the underlying operating system and its timers and schedulers. I've experienced that garbage collection going on in parallel can lead to excessive sleep.

When doing "real time" simulations you have to correct your main loop for the inaccuracies of sleep. This can be done by calculating the expected time of wake-up and comparing that to the actual time of wake-up and correcting for the difference in the next loop.

If you need better performance, have a look at the Java Real-Time System specification. I haven't used it myself so I can't provide further details.

DeltaLima
  • 5,864
  • 1
  • 16
  • 32
5

I did not find Thread.sleep to be accurate. In fact, I found that it seems to sleep less than what it promises.

Results when configured to sleep 1 millisecond:

********* Average elapsed time = 957 micro seconds

Below is my test:

public static void main(String[] args) throws InterruptedException {
    List<Long> list = new ArrayList<Long>();

    int i= 0;
    while(i <=100){

        long authStartTime = System.nanoTime();
        Thread.sleep(1);
        long elapsedTime = System.nanoTime() - authStartTime;
        System.out.println("*****"+elapsedTime/1000+ " mics");
        list.add(elapsedTime);
        i++;
    }

    long sum=0;
    for(long l : list){
        sum = sum + l;
    }
    System.out.println("********* Average elapsed time = "+sum/list.size()/1000+" micro seconds");
    System.exit(0);
}
Scott Weldon
  • 9,673
  • 6
  • 48
  • 67
mario
  • 51
  • 1
  • 3
3

From the Java language specification.

Thread.sleep causes the currently executing thread to sleep (temporarily cease execution) for the specified duration, subject to the precision and accuracy of system timers and schedulers. The thread does not lose ownership of any monitors, and resumption of execution will depend on scheduling and the availability of processors on which to execute the thread.

Andromeda
  • 1,370
  • 2
  • 10
  • 15