Java - Thread.sleep inside run method

user3421485 picture user3421485 · Jun 25, 2014 · Viewed 9.1k times · Source

I'm following a tutorial and below is the run method to generate logic and frame updates. I understand how the ticks are updated 60 ticks/second but I don't understand how we adjust frame per second here.

Right now with Thread.sleep(2), frame per second is around 460. Without it the numbers go way up, around 10 million updates per second. The code Thread.sleep(2) suspends the thread for only 2 milliseconds right? Why/how does Thread.sleep exactly work here to drop it so low?

Isn't it simpler to create a nsPerFrame = 1000000000D/ (FPS)D to set whatever FPS I want the way he did with ticks?

public void run(){
    long lastTime = System.nanoTime();
    double nsPerTick = 1000000000D / 60D;

    int frames = 0;
    int ticks = 0;

    long lastTimer = System.currentTimeMillis();
    double delta = 0;

    while(running){
        long now = System.nanoTime();
        delta += (now - lastTime) / nsPerTick;
        lastTime = now;

        while(delta >= 1){
            ticks++;
            tick();
            delta-= 1;
        }

        try{
            Thread.sleep(2);
        } catch(InterruptedException e){
            e.printStackTrace();
        }

        frames++;
        render();

        if(System.currentTimeMillis() - lastTimer >= 1000){
            lastTimer += 1000;
            System.out.println(ticks + "," + frames);
            frames = 0;
            ticks = 0;
        }
    }
}

Answer

hiergiltdiestfu picture hiergiltdiestfu · Jun 25, 2014

Well sleep(2) is called repeatedly in your running-loop so the hard upper limit in this case is 500 cycles per second (1000 ms divided by 2 ms), and your measured 460 fps is pretty close to that.

Sure enough you can adjust the sleep duration according to your needs and if needed stuff it into the somewhat higher-precision method Thread#sleep(long, int) where the second parameter is "nanos" (take a look at the docu for caveats!).

The formula for your case is FPS = 1000 ms / sleep duration in ms. From which follows: sleep duration in ms = 1000 ms / FPS.