Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accurate Sleep for Java on Windows

Does anyone know a Library which provides a Thread.sleep() for Java which has an error not higher than 1-2 Millisecond?

I tried a mixture of Sleep, error measurement and BusyWait but I don't get this reliable on different windows machines.

It can be a native implementation if the implementation is available for Linux and MacOS too.

EDIT The link Nick provided ( http://blogs.oracle.com/dholmes/entry/inside_the_hotspot_vm_clocks ) is a really good resource to understand the issues all kinds of timers/sleeps/clocks java has.

like image 656
HaBaLeS Avatar asked May 05 '09 09:05

HaBaLeS


People also ask

How accurate is Java sleep?

Incredibly inaccurate. You have to deal with the inconsistencies of the OS process scheduler, the time spent context switching, the Java VM, etc. Well documentation is silent on its accuracy- it talks a lot about accuracy for System.

Is there a sleep command in Java?

Thread. sleep() method can be used to pause the execution of current thread for specified time in milliseconds.

Is it safe to use thread sleep in Java?

Thread. sleep is bad! It blocks the current thread and renders it unusable for further work.


3 Answers

To improve granularity of sleep you can try the following from this Thread.sleep page.

Bugs with Thread.sleep() under Windows

If timing is crucial to your application, then an inelegant but practical way to get round these bugs is to leave a daemon thread running throughout the duration of your application that simply sleeps for a large prime number of milliseconds (Long.MAX_VALUE will do). This way, the interrupt period will be set once per invocation of your application, minimising the effect on the system clock, and setting the sleep granularity to 1ms even where the default interrupt period isn't 15ms.

The page also mentions that it causes a system-wide change to Windows which may cause the user's clock to run fast due to this bug.

EDIT

More information about this is available here and an associated bug report from Sun.

like image 96
Pool Avatar answered Sep 21 '22 20:09

Pool


This is ~5 months late but might be useful for people reading this question. I found that java.util.concurrent.locks.LockSupport.parkNanos() does the same as Thread.sleep() but with nanosecond precision (in theory), and much better precision than Thread.sleep() in practice. This depends of course on the Java Runtime you're using, so YMMV.

Have a look: LockSupport.parkNanos

(I verified this on Sun's 1.6.0_16-b01 VM for Linux)

like image 40
Joao da Silva Avatar answered Sep 23 '22 20:09

Joao da Silva


Unfortunately, as of Java 6 all java sleep-related methods on Windows OS [including LockSupport.awaitNanos()] are based on milliseconds, as mentioned by several people above.

One way of counting precise interval is a "spin-yield". Method System.nanoTime() gives you fairly precise relative time counter. Cost of this call depends on your hardware and lies somewhere 2000-50 nanos.

Here is suggested alternative to Thread.sleep():

   public static void sleepNanos (long nanoDuration) throws InterruptedException {
        final long end = System.nanoTime() + nanoDuration;
        long timeLeft = nanoDuration;
        do {
            if (timeLeft > SLEEP_PRECISION)
                Thread.sleep (1);
            else
                if (timeLeft > SPIN_YIELD_PRECISION)
                    Thread.yield();

            timeLeft = end - System.nanoTime();
        } while (timeLeft > 0);
    }

This approach has one drawback - during last 2-3 milliseconds of the wait hit CPU core. Note that sleep()/yield() will share with other threads/processes. If you are willing to compromise a little of CPU this gives you very accurate sleep.

like image 27
Andy Malakov Avatar answered Sep 25 '22 20:09

Andy Malakov