Sleeping Better

The animation loop in run() depends on a good timer and the accuracy of the sleep() call. The previous major section dealt with alternatives to currentTimeMillis(). In this section, I consider ways of improving the sleep() code in run(), so the required frame rate is consistently achieved.

The SleepAcc class measures sleep accuracy. Example 2-4 calls sleep() with increasingly small values and measures the actual sleep time using the Java 3D timer.

Example 2-4. Measuring sleep() accuracy

import java.text.DecimalFormat;
import com.sun.j3d.utils.timer.J3DTimer;

public class SleepAcc
{
  private static DecimalFormat df;

  public static void main(String args[])
  {
    df = new DecimalFormat("0.##");  // 2 dp

    // test various sleep values
    sleepTest(1000);
    sleepTest(500);
    sleepTest(200);
    sleepTest(100);
    sleepTest(50);
    sleepTest(20);
    sleepTest(10);
    sleepTest(5);
    sleepTest(1);
  } // end of main()


  private static void sleepTest(int delay)
  {
    long timeStart = J3DTimer.getValue();

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

    double timeDiff =
       ((double)(J3DTimer.getValue() - timeStart))/(1000000L);
    double err = ((delay - timeDiff)/timeDiff) * 100;

    System.out.println("Slept: " + delay + " ms  J3D: " +
                          df.format(timeDiff) + " ms  err: " +
                          df.format(err) + " %" );
  }  // end of sleepTest()

} // end of SleepAcc class

The difference between the requested and actual sleep delay is negligible for times of 50 ms or more and gradually increases to a +/-10 to 20 percent error at 1 ms. A typical ...

Get Killer Game Programming in Java now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.