Question

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.

Was it helpful?

Solution

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.

OTHER TIPS

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)

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.

There are no good reasons to use Thread.sleep() in normal code - it is (almost) always an indication of a bad design. Most important is, that there is no gurantee that the thread will continue execution after the specified time, because the semantics of Thread.sleep() is just to stop execution for a given time, but not to continue immedeately after that period elapsed.

So, while I do not know what you try to achieve, I am quite sure you should use a timer instead.

JDK offers the Timer class.

http://java.sun.com/j2se/1.5.0/docs/api/java/util/Timer.html

Reading the docs clearly indicates that beyond the plumbing to make this a generalized framework, it uses nothing more sophisticated than a call to Object.wait(timeout):

http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html#wait(long)

So, you can probably cut the chase an just use Object#wait yourself.

Beyond those considerations, the fact remains that JVM can not guarantee time accuracy across platforms. (Read the docs on http://java.sun.com/j2se/1.5.0/docs/api/java/lang/System.html#currentTimeMillis())

I think you'll need to experiment with a compromise solution combining Timer and busy polling if you want to want the highest timing precision possible on your platform. Effectively Object#wait(1) -> System#nanoTime -> calculate delta -> [loop if necessary].

If you are willing to roll your own, JNI pretty much leaves it wide open for platform specific solutions. I am blissfully un-aware of Window's internals, but obviously if the host OS does provide sufficiently accurate realtime timer services, the barebones structure of setting up a timerRequest(timedelta, callback) native library shouldn't be beyond reach.

The Long.MAX_VALUE hack is the working solution.

I tried Object.wait(int milis) to replace Thread.sleep, but found that Object.wait is as accurate as Thread.sleep (10ms under Windows). Without the hack, both methods are not suitable for any animation

Use one of the Thread::join overrides on the current thread. You specify the number of milliseconds (and nanoseconds) to wait.

You could try using the new concurrency libraries. Something like:

private static final BlockingQueue SLEEPER = new ArrayBlockingQueue(1);
public static void main(String... args) throws InterruptedException {
    for(int i=0;i<100;i++) {
        long start = System.nanoTime();
        SLEEPER.poll(2, TimeUnit.MILLISECONDS);
        long time = System.nanoTime() - start;
        System.out.printf("Sleep %5.1f%n", time/1e6);
    }
}

This sleeps between 2.6 and 2.8 milliseconds.

Sounds like you need an implementation of real-time Java.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top