Working with a nanoTime() Timer

I’m developing a high speed scroller. It is extremely important that I have a high resolution timer. Since I’m restricting myself (perhaps needlessly?) to working in pure Java, this has narrowed my search to utilizing the newly supported System.nanoTime() method in Java 1.5b.

Here’s how I’m thinking of utilizing it. Perhaps you can tell me if I’m on the right track. In the main game thread/static void main we’ve got:


long startTime = System.nanoTime();
long endTime;
double difference;
int FPS = 50;
int sec = 0;

while(true)
{
   endTime = System.nanoTime();
   difference = ((double)(endTime - startTime));

   if(difference >= ((double)(1000000000 / FPS)
   {
       startTime = endTime;
       sec++;
       //Frame!
   }
    if(sec == FPS)
   {
       sec = 0;
       //Second!
   }
}

Since Thread.sleep() is unreliable, this is the only method I can think of to keep a steady beat. The only problem with this code is the junk that goes on during and in between frames. Right now with just the code in this loop, it’s able to keep time. I imagine that once things get processor heavy, the code will desync from the system clock. If such is the case, the computations done each frame need to take 1/FPS*1billion nanoseconds or less to complete or the game will lag behind. Additionally, this timer is more prone to to lag when other programs are open. Even unreliable methods that rely on Thread.sleep(1) are stronger against such things due to the way Java handles the associated threading.

Any suggestions as to how I can safegard this? Perhaps I am underestimating Java and should assume it has the capability to compute heavy things within my time constraints? (I doubt it. As it is now, I have to “preload” all my graphics long before I expect to use them or the game will lag.)

Any other approaches to this would be greatly appreciated. Keep in mind that I wish to keep things purly in Java. I’m very much the type of person who wants to “reinvent the wheel” and if I get over my head dealing with dlls and other languages, I’ll spend too much time trying to learn the finer details of such things rather than on the game.

Edit: It seems that I might be able to make this a bit more robust if I could throw it in a thread and use yield(). Could someone explain to me exactly how yield() works? The API is a bit misleading. If it waits for other threads, does this mean that it waits for any one of them to synchronize? Or does it merely perform the same thing that sleep() does only without a specified duration? If the latter, how might I utilize yield() to make a thread pause for a certain amount of time (i.e: the length of a frame)?

This is the dead simple loop ripped out of the 4K game im working on atm.
It functions fine even with the Thread.yield() ommited (atleast on Windows)

int frameCount = 0;
long startTime = System.nanoTime();
final int NANO_FRAME_LENGTH = 1000000000/60; //frame length in nanoseconds for 60fps
while(true)
{
// game code
frameCount++;
bs.show();
while((System.nanoTime()-startTime)/NANO_FRAME_LENGTH <frameCount)
{
   Thread.yield();
}
}

If you want a more complex solution, have a look at GageTimer. (java.dnsalias.com)

I’ve been looking around a bit for a good high resolution timer myself, and I found a tutorial at http://weblogs.java.net/cs/user/view/cs_msg/2744 but it keeps giving me an error that it can’t find the import library sun.misc.Perf. Does this library come default with Java, or do you have to download it seperately?

sun.misc.Perf is the hidden hires timer that was included in java 1.4.x. (not sure the exact version it was added)
It may well have been removed in 1.5 as it isn’t part of core java or extensions.

You can exchange usage of sun.misc.Perf for the equivalent calls to System.nanoTime() without much hassel, to make the timer you found work in 1.5.

Abuse,

That timer code you listed a couple messages above, would you consider that a solid timer for a game these days?

I’m really just trying to find a good timer that uses nanotime now that it’s available. Your timer above has me worried however that it’s just running the thread with no pausing at all (is that a bad thing?).

Any help would be appreciated.

I just answered a little bit of my own question: Running that timer causes the CPU to ramp up to 100%, even if I tell it to only do 10fps (which it does only do 10fps in that case, but still with high CPU). Should I be using a thread.sleep method instead?

I could sure use some help on this, as timers are that one great and important concept that I just haven’t been able to grasp yet.

See the FAQ at the bottom of the page http://java.dnsalias.com/

It has info about timers and thread.sleep/yield and the 100% CPU thing.

Ah, so the answer is: When using Thread.yield(), the CPU will probably ramp up to 100%, but that is good and expected, and it shouldn’t interrupt other applications that are running concurrently.

That’s the way I understood that page anyway. If I’m wrong, please let me know.

If you want to fall back to 1.4.2, LWJGL has a high resolution timer.

www.lwjgl.org