How does the new Thread.sleep() work?

I just saw the new System.nanoTime(), I also notice that Thread has a new sleep(millis, nanos) method. If I want to use the nanoTime() timer do I use sleep(0, myNanos)? Is that the proper way to implement a timer?

AFAIK Thread.sleep has always had an optional nanos argument but because you are constrained by the O/S thread scheduling resolution - which is on the order of 10-100ms on Windows - you’re not going to see anything like that resolution.

There are almost no circumstances where you need to use Thread.sleep() writing games anyway :slight_smile: I recommend spinning on a hires timer using Thread.yield() which works 100% reliably. Provided you’ve got a hires timer of course :wink:

Cas :slight_smile:

[quote]AFAIK Thread.sleep has always had an optional nanos argument but because you are constrained by the O/S thread scheduling resolution - which is on the order of 10-100ms on Windows - you’re not going to see anything like that resolution.
[/quote]
Thread.sleep already (in 1.4) gives resolution down to 1 or 2ms on Windows. The new nanoTime method will make it much easier to measure and thus demonstrate this.

Looks like Windows thread latency has got better in recent years.

I suppose that might be an effect of processors speeding up by a factor of 10 :slight_smile:

Cas :slight_smile:

Actually, the JVM authors hacked windows to allow Thread.sleep() to return within 1-2 ms. Unfortunately, using Thread.sleep() with values of 10 or less can cause the system timer to drift. Thus, Thread.yield() remains the best solution.

Ah, good.

Cas :slight_smile:

The clock drift problem has been fixed (or so they claim).
Fixed in 1.3.1_04, 1.4.0_02, hopper.

http://developer.java.sun.com/developer/bugParade/bugs/4500388.html

Actually, it’s not fixed per say. Instead, you’re supposed to use the flag “-XX:+ForceTimeHighResolution” when you’re running a program that has a sleep with less than 10ms. :frowning:

Edit: Sorry, here’s a link.

hang on…
Does this timer drift affect all applications on the machine? (Java and native apps. that use the same system timer?) :o

So my (pseudo)code could look something like:

while (true) {
  startTime = System.nanoTime();
  // Input, process, output...
  Thread.yield(0, FPS_CONSTANT - (System.nanoTime() - startTime));
}

I’m trying to achive something like the GAGE Timer but using only the Java API… Pre Java 1.5 I’ve used GAGE but I want my game to be as portable as Java so to say…

[quote]hang on…
Does this timer drift affect all applications on the machine? (Java and native apps. that use the same system timer?) :o
[/quote]
Yep. Sorry. If you’ve been wondering why your computer clock always seems faster than your other clocks, that’s probably why.

Edit: I should probably point out that we’re talking about the actual time keeping device inside your computer drifting. That means that not only is one clock drifting, ALL the clocks are drifting. Except for the CPU clock. That has its own problems with drift. and generally isn’t a very good way of measuring true time.

[quote]So my (pseudo)code could look something like:

while (true) {
  startTime = System.nanoTime();
  // Input, process, output...
  Thread.yield(0, FPS_CONSTANT - (System.nanoTime() - startTime));
}

I’m trying to achive something like the GAGE Timer but using only the Java API… Pre Java 1.5 I’ve used GAGE but I want my game to be as portable as Java so to say…
[/quote]
Save yourself the trouble and just use GAGE. If you don’t distribute the DLL the timer will still work, but it will work as precisely as System.currentTimeMillis() will let it. (10-50ms) Otherwise, feel free to dig in the GAGETimer source. It should be pretty easy to understand. The general algorithm (the best one anyway) is:


long time = System.currentTimeMillis();
long sleepTime = 100; //100 ms per frame

while(true)
{
    ....
    while(System.currentTimeMillis() < time+sleepTime) Thread.yield();
    time += sleepTime;
}

If the game begins to fall behind, it will generate frames faster until it can catch up.

Edit: And just in case you weren’t aware, there’s a new version of GAGETimer that uses System.nanotime() on 1.5. No need for the DLL unless you want Hi-Res timing under 1.4.

The project I’ll be using the timer from is one given by the university and they’ll appreciate if we write as much code ourselves as possible (would not be my option IRL however) so I guess I’ll go look in the GAGE source and try to write something similar with Java 1.5.