I’m new to game development with Java and I’ve noticed some odd behavior with Thread.sleep.
It seems that the accuracy of Thread.sleep is suspect. Take the following code as an example…
public class ClockTest
{
public static void main(String[] args)
{
for (int i = 1; i <= 20; i++)
{
// Using absolute clock time
long start = System.currentTimeMillis();
try
{
// Sleeping for 5 milliseconds
Thread.sleep(5);
}
catch (InterruptedException e)
{
e.printStackTrace();
System.exit(1);
}
long end = System.currentTimeMillis();
// Output results *after* the time captures to reduce extraneous code's execution time
System.out.println("Attempt " + i + ": " + (end - start) + " millsecs");
}
}
}
…which produces…
Attempt 1: 6 millsecs
Attempt 2: 6 millsecs
Attempt 3: 5 millsecs
Attempt 4: 5 millsecs
Attempt 5: 5 millsecs
Attempt 6: 5 millsecs
Attempt 7: 5 millsecs
Attempt 8: 5 millsecs
Attempt 9: 5 millsecs
Attempt 10: 5 millsecs
Attempt 11: 21 millsecs <-- ouch
Attempt 12: 5 millsecs
Attempt 13: 5 millsecs
Attempt 14: 5 millsecs
Attempt 15: 5 millsecs
Attempt 16: 5 millsecs
Attempt 17: 6 millsecs
Attempt 18: 5 millsecs
Attempt 19: 5 millsecs
Attempt 20: 5 millsecs
I’m using the 1.6.0_01 JDK under Linux (Intel single core CPU). As you can see, sometimes, Thread.sleep can take over 4x the amount of time requested. Most of the time, it seems that it can handle a 5 millisecond request time, and so it’s not that the OS time facilities that the JVM uses can’t handle that small of a resolution. It would seem that other factors are involved… maybe JVM native threads (e.g for garbage collection)Huh
Can anyone explain the difference in the numbers? Also, how do you release CPU time to other threads (e.g. the AWT thread) while still being able to keep a constant frame rate if Thread.sleep durations are not consistent?