Removed…
Thread.yield() uses a lot more CPU than Thread.sleep(). Also you’ll get a lot more “respect” by using proper coding conventions and doing it right.
Also “i would love to use sleep but it is not possible with present java to sleep so short times”, can’t this be fixed with infinite sleeping thread trick.
Yield != sleep. It essentially means “take this thread out of the running queue, search for runnable threads, put them on the queue if they are available, and if they aren’t available, continue running this thread”. That is a of work you are adding to your while loop, and it does not prevent that thread from still eating up all CPU usage (where as sleep does).
Yielding also has dramatically different effects on different operating systems. In Windows Vista and 7, the OS will generally sleep your thread more often (it is a lot more difficult for threads to starve each other from Vista onwards). On Linux and XP, it won’t. As a result parts of your app can freeze on one OS, and not on another, all because you used yield.
In my own code I sleep for the length of an ideal frame, minus the length that the last frame took (I think this was already suggested above). In practice the ideal frame time is around 15, a tad faster then 60fps. This always worked well for me, and I’d recommend it over yielding, spinning or sleep(1)'s. I would only use something more advanced if this does not work for you!
There is a good reason why Windows, and Mac OS, don’t use high resolution timers by default. It is the same reason why Java, and especially JavaScript, also don’t support a high resolutions for their timers. It is because it significantly drains the battery life on laptops and other devices. Chrome developers experimented with having a high-resolution timer, and found they used up an extra 25% of battery time. That is a quarter of the life spent solely on keeping the timer accurate. In one of the Mac OS X updates Apple reduced the internal timer, as it significantly increased battery time. IE 9 even has different resolutions, depending on if you are plugged into the mains or not.
Spinning or repeatedly yielding will use up more battery power!
Removed…
Yield need not pause, or in fact do anything at all. Do take note of what jdk7 says about yield:
http://download.oracle.com/javase/7/docs/api/java/lang/Thread.html#yield()
Removed…
The only thing you should be worrying about is:
- update logic
- draw everything
- sleep for (desired amount - time the logic and drawing took)
- goto 1
Btw: The graphics card isn’t exactly…human. It doesn’t need to “rest”
Why do you need to let the graphics card rest?
Frame rate limiting is only useful on laptops. It’s either to reduce power consumption or reduce graphics card heat. My little laptop likes to be 89 degrees if I don’t set my settings carefully. Only power consumption is relevant in this case of course, but letting a Java2D program run wild doesn’t sound that bad…
GPU will get less heat(less malfunction) if you just draw everything on short period and rest until next frame.
Exactly. This idea that you need to rest between every draw is simply not true, and will end up using more power, and generate more heat.
Graphics cards can trivially draw 200 to 400 images per frame.
Java7 didn’t change the implementation, they changed the docs to be more accurate. The behavior of Thread.yield() is os-dependent. In fact, from poking around hotspot’s code, it looks like there are places where yield is temporarily disabled, i.e. it does nothing at all. Solaris has a mode where more than 100 yields/sec are ignored, and so on.
The short of it is, yield will probably lower the total CPU usage simply because the OS scheduler may sleep it as a side effect, but you cannot depend on there being a sleep or in fact having yield do anything at all. It’s a hint, nothing more.
That’s the moneymaker. Many thanks for that, teletubo. This really smooths out the drawing, compared to using a static sleep(long)