I'm programming a game in Java and I limit the FPS to 60. I figured out 2 different ways to get the same result, but I'm wondering which of them is the better/cleaner way to do it. Or maybe you have a different idea.
while(System.nanoTime() - thisFrame < fps_limit);
or
Thread.sleep(sleepingTime);
My thinking is that the while loop effects the CPU more than Thread.sleep, am I right?
Thanks in advance for your help!
Dom
You have the following main options:
While loop - This will consume CPU cycles and often will actually stop the system because while you are looping, other threads cannot run (on a one-core machine).
Thread.sleep() - This can be effective but you need to remember that is not guaranteed to wait the specified time.
DelayQueue - More up-to-date. Better/accurate timing.
ScheduledThreadPoolExecutor - Still more up-to-date than DelayQueue. Uses a Thread Pool.
You're right, while both with achieve what you're trying to do, the while loop will keep the processor occupied, consuming CPU time.
In contrast, Thread.sleep() frees the processor for the amount of time mentioned.
So, Thread.sleep() is better.
Both the answers posted already are good - sleep is better than loop. However, you can go into much more detail about how to write a good loop. If you are interested, here is a great resource: http://www.java-gaming.org/index.php?topic=24220.0
It covers topics like variable timestep and interpolation, which can be used to make your graphics run extremely smoothly. This solves the issues Thread.sleep has with not being 100% accurate in its timing as well as preventing your graphics from appearing jerky if your game performs some calculation that takes some time.
What I would do (pseudo code).
//timepast since last loop in ms
timepast = 0
fpslimit = 60
finished = true;
//while the game is running
while(runnning)
{
timepast += timeSinceLastrun
if(timepast > 1second/fpslimit && finished)
{
finished = false
dostuff(timepast)
}
//sleep for the time of 1second/fpslimit - timepassed to avoid cpu blocking
Thread.sleep((1second/fpslimit) - timepast )
}
dostuff(deltatime)
{
//do stuff in the end after it finished set
//finished to true so dostuff can be called again
finished = true
timepast=0
}
In this way you can easily limit the fps with a variable and dont need to block other threads.
as OldCurmudgeon said thread.sleep dosnt block other threads in java and make processor time available.
Thread.sleep causes the current thread to suspend execution for a
specified period. This is an efficient means of making processor time
available to the other threads of an application or other applications
that might be running on a computer system
Also you can pass timepast to the dostuff method as a deltatime so the game runs the same on all devices (same speed).
I concur with #ayush - while loops are usually blocking functions, whereas threads are more like interrupt-driven or parallel programming functions. I'm a bit green on Java, but could you not setup a timer rather than sleeping?
Yeah it looks like Timer constructs, like in C++, are available. Check this out: Timer in Java Thread
You should use neither of them. Please take a look at the documentation for ScheduledThreadPoolExecutor
In particular you are looking at this function
ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long initialDelay, long period, TimeUnit unit)
while loop will use CPU resource and it is good only if your avg.waiting time is very less and expecting precision.
Thread.sleep() is fine if no precision is expected as CPU priority will change after thread wakes up and it may or may not be scheduled immediately to run and it also should not to be used like this
while(! canContinue()) {
Thread.sleep(1000);
}
For the above case, alternative is these cases better to use wait()/notify() if you want to suspend the current thread and wait for another thread to process something and then notify the current thread to continue.
some references you can read,
http://tutorials.jenkov.com/java-concurrency/thread-signaling.html
http://www.jsresources.org/faq_performance.html#thread_sleep
Related
I am trying to make an intro to a game with some strings that I want one to wait for another to pop up, and I don't directly want to use Thread.sleep() for it to wait, because I am not sure if that is the best option. Is there any other way to make something wait than making the thread sleep, or will I just have to make the thread sleep?
If this is a game you shouldn't use sleeps or timers.
Typically games have their own internal clock mechanism. This means you will try to render the frames as fast as possible. Your OnRender method will be invoked with the current time of the game. You can use this to determine if enough time has passed to go to the next screen.
This means you will be given a point in time A in frame 1. You'll be given the Delta or another point in time B in frame 2. You can determine how much time has passed by using the delta or calculating the delta yourself. This is a very efficient mechanism for timing situations and worked quite well when games were single threaded. The idea of any program is to never block for anything.
The reasons things typically block is due to I/O such as reading from disk, the network or putting data on the GPU. In your situation you can do everything without blocking.
Here is a decent page on this https://gamedev.stackexchange.com/questions/1589/fixed-time-step-vs-variable-time-step
There's a standard mechanism for this: Object.wait() and Object.notify() (with their overloads / variants). You simply wait for some event to occur in one thread, and some other thread is responsible for notifying you (or everyone, in case of notifyAll) of that occurrence.
You can also make use of the new Condition mechanism introduced in java.util.concurrent.
If you're making this in a game, why not try using something like Actions in libgdx? You just chain different actors together. Whenever a property like visibility or position reaches the value you want, you trigger the next action. Properties conditions are checked during each update loop of your game.
Or if its a swing app, use a timer to check these properties.
long t1=0,t2=0;
long nanoWaitTime=10000; //to wait at least 10000 nano-seconds
t1=System.nanoTime();
//start waiting
long count=0;
boolean releaseCpuResources=true;
while(Math.abs(t2-t1)<nanoWaitTime)
{
t2=System.nanoTime(); //needs maybe 1000 cycles of cpu to get this value.
//so this is like busy-wait
//and minimum step may be 1 micro-seconds or more
if(releaseCpuResources)
{
count++;
if(count>1000)Thread.sleep(1);//after too many iterations, cpu gets overwhelmed
//so Thread.sleep makes it better for large waiting
//times
//but precision is lost. Like uncertainity principle
//but in a quantized fashion
}
}
// here continue to work after waiting
The resolution or precision may not be what you want in for all cpus.
I normally use infinite loop as in the way below:
public static boolean start = false;
while(!start) {
doMyLogic();
}
but a friend said you need to have a small delay inside the while-true loop (like bellow), otherwise it may tend to cause memory issues and also it is not a good practice.
Suggested way:
while(!start) {
Thread.sleep(few_miliseconds); // 500 ms
doMyLogic();
}
Kindly advise me the impact of suggested way. Am I doing it right?
I would use a ScheduledExecutorService
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
doMyLogic();
}
}, 500, 500, TimeUnit.MILLISECONDS);
This service can be re-used for many repeating or delayed tasks and can be shutdown() as required.
Well, I don't think it would have memory issues (unless your doMyLogic method has memory issues), because any memory leaks will manifest themselves regardless of the delay. The real benefit of the sleep is that in most instances, the code doesn't need to be doMyLogic as fast as the computer can. For example, let's say doMyLogic is checking to see if a file was created in a directory. It would not be necessary to have the computer check several hundred times a second for that scenario (which would require a lot of CPU and disk I/O), when 1 time a second may be sufficient.
The biggest impact of not having the timing is using extra CPU time and other resources that your logic function has, in most cases with no discernable impact to the end user.
Not memory issues, but you are blocking CPU. Definitely use a delay.
It also depends a bit on the doMyLogic() method.
It's always a good practice to insert sleep in a (semi) infinite loop so when code execution reaches the sleep, other threads can be executed too.
If you don't have a pause, your CPU is constantly doing something. You are effectively blocking the CPU. However, if you add a pause (sleep()) you give the CPU a break to do other things.
Today I had an interview on which I asked candidate quite usual and basic question about the difference between Thread.sleep() and Object.wait(). I expected him to answer something like like this, but he said these methods basically are the same thing, and most likely Thread.sleep is using Object.wait() inside it, but sleep itself doesn't require external lock. This is not exactly a correct answer, because in JDK 1.6 this method have following signature.
public static native void sleep(long millis) throws InterruptedException;
But my second thought was that it's not that ridiculous. It's possible to use timed wait to achieve the same effect. Take a look at the following code snippet:
public class Thread implements Runnable {
private final Object sleepLock = new Object();
// other implementation details are skipped
public static void sleep(long millis) throws InterruptedException {
synchronized (getCurrentThread().sleepLock){
getCurrentThread().sleepLock.wait(millis);
}
}
In this case sleepLock is an object which is used particularly for the synchronization block inside sleep method. I assume that Sun/Oracle engineers are aware of Occam's razor, so sleep has native implementation on purpose, so my question is why it uses native calls.
The only idea I came up with was an assumption that someone may find useful invocation like Thread.sleep(0). It make sense for scheduler management according to this article:
This has the special effect of clearing the current thread's quantum and putting it to the end of the queue for its priority level. In other words, all runnable threads of the same priority (and those of greater priority) will get a chance to run before the yielded thread is next given CPU time.
So a synchronized block will give unnecessary overhead.
Do you know any other reasons for not using timed wait in Thread.sleep() implementation?
One could easily say Occam's Razor cuts the other way. The normal/expected implementation of the JVM underlying JDK is assumed to bind java 'threads' onto native threads most of the time, and putting a thread to sleep is a fundamental function of the underlying platform. Why reimplement it in java if thread code is going to be native anyway? The simplest solution is use the function that's already there.
Some other considerations:
Uncontested synchronization is negligible in modern JVMs, but this wasn't always so. It used to be a fairly "expensive" operation to acquire that object monitor.
If you implement thread sleeping inside java code, and the way you implement it does not also bind to a native thread wait, the operating system has to keep scheduling that thread in order to run the code that checks if it's time to wake up. As hashed out in the comments, this would obviously not be true for your example on a modern JVM, but it's tough to say
1) what may have been in place and expected at the time the Thread class was first specified that way.
and
2) If that assertion works for every platform one may have ever wanted to implement a JVM on.
Do you know any other reasons for not using timed wait in Thread.sleep() implementation?
Because the native thread libraries provide a perfectly good sleep function: http://www.gnu.org/software/libc/manual/html_node/Sleeping.html
To understand why native threads are important, start at http://java.sun.com/docs/hotspot/threads/threads.html
Version 1.1 is based on green threads and won't be covered here. Green threads are simulated threads within the VM and were used prior to going to a native OS threading model in 1.2 and beyond. Green threads may have had an advantage on Linux at one point (since you don't have to spawn a process for each native thread), but VM technology has advanced significantly since version 1.1 and any benefit green threads had in the past is erased by the performance increases over the years.
Thread.sleep() will not be woken up early by spurious wakeups. If using Object.wait(), to do it properly (i.e. ensure you wait enough time) you would need a loop with a query to elapsed time (such as System.currentTimeMillis()) to make sure you wait enough.
Technically you could achieve the same functionality of Thread.sleep() with Object.wait() but you would need to write more code do it correctly.
This is also a relevant and useful discussion.
When a thread is called the sleep method, the thread will be added into a sleep queue. If the compute clock frequency is 100HZ, that means every 10ms the current running process will be interrupted. After reserve the current context of the thread, then it will decrease the value (-10ms) for each thread. When it comes to zero, the thread will move to "waiting for CPU" queue. When time slice comes to this thread, it will be running again. Also because this which not immediately become running, so the time actually sleeps is larger than the value it set.
I wrote a daemon which was structured like this:
while( true ) {
// do some stuff
Thread.sleep( 1000 );
}
I noticed it was using a very large amount of CPU - up to 100%. I have had a similar daemon on my production servers for some months with the same CPU problem.
Yesterday I refactored the code to use TimerTask. Immediately I noticed that CPU usage had decreased on my dev box. So I decided to deploy to production and double-check using Munin. Here are the graphs:
A couple of points:
There is absolutely nothing else running on the production server except the JVM.
There are no other application threads running
It was definitely executing the old-style code at the correct periodic intervals - I always write to the log each time the thread executes.
So: why is Thread.sleep so inefficient compared to TimerTask?
Three possibilities I can think of:
You have a huge number of threads doing this, and they're context switching all the time. Using a timer will mean there's only one thread instead. On the other hand, that means you will only get one task executing at a time.
You have a continue; statement somewhere in your loop before the sleep, so even if the main body of work of the loop isn't executing very frequently, something is. It's hard to say without seeing some more concrete code though.
You have a broken JVM/OS combination. This seems pretty unlikely, admittedly.
A simple loop just executing Thread.sleep(1000) repeatedly should be very cheap - and that should be easy for you to verify, too.
Compare the speed of your processor, a thread and a timertask. The timertask is a slower thread (much slower).
Is tight looping in a program bad?
I have an application that has two threads for a game-physics simulator. An updateGame thread and a render thread. The render thread is throttled by causing the thread to sleep for some milliseconds (to achieve the frame-rate I want) and the updateGame thread (that updates my in game objects positions based off some physics equations) was previously throttled by a 10 millisecond sleep.
However, I recently unthrottled the updateGame thread and the simulation of my objects movement seems to be significantly more realistic now that I have taken out that 10ms sleep. Is it bad to hot loop or have a tight loop?
private class UpdateTask implements Runnable
{
private long previousTime = System.currentTimeMillis();
private long currentTime = previousTime;
private long elapsedTime;
public void run()
{
while(true)
{
currentTime = System.currentTimeMillis();
elapsedTime = (currentTime - previousTime); // elapsed time in seconds
updateGame(elapsedTime / 1000f);
try {
Thread.currentThread().sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
previousTime = currentTime;
}
}
}
In this example I'm just sleeping for 1ms (and from my understanding with how millisecond accuracy and the sleep function works this is probably more like 5-10ms. If I sleep for any more than this it starts to have impacts on the accuracy of my collision detection and physics model.
Is it a bad practice to have tight loops or loops with 1ms sleeps in them? Is there something else I should do instead?
I read a really great post about efficiently and effectively executing physics calculations loop: Fix Your Timestep!
When a game is running that is usually the main application that the user cares about so tight looping is not that big of a deal. What you really should do though schedule your updates. You should know how long -- at your target framerate -- that your frame has to execute. You should measure the time that your frame took and only sleep for the time that your frame took minus that known frame time. That way your system will lock into a frame rate and not vary with the amount of time that your frame takes to render.
Another thing is that I don't believe that Thread.sleep has a very good resolution, well over 5 milliseconds, you may want to look for a more accurate timer available for Java.
It's only "bad" if it has an adverse impact on something else in your system. Rather than sleeping for 1ms, you might block on a condition that warrants updating, with a minimum of 1ms. That way you'll always sleep for at least 1ms, and longer if there's nothing to do.
As Adam has pointed out in his answer, there may be an adverse impact on the performance of the system.
I've also tried making games in a very similar manner (having a rendering and motion calculations on separate threads) and I have found that not having the Thread.sleep will cause the Java application to take a very significant portion of the CPU time.
Another thing to consider is that the system timer itself. As you've mentioned, although the Thread.sleep method is takes in the number of milliseconds to sleep, but that precision is dependent (as noted in the API specifications) on the timer provided by the operating system. In the case of Windows NT-based operating systems, the timer resolution is 10 milliseconds. (See also: System.currentTimeMillis vs System.nanoTime)
Yes, it is true that having the Thread.sleep has the potential to decrease the performance of your application, but not having that can cause the system utilization by the application to skyrocket.
I would guess the decision comes down to whether the application should take up a significant portion of the system utilization, or to act nice and share the CPU time with the other applications running on the system.
Also consider laptop users, running a tight loop continuously will keep the CPU running hard, and this will chew through their battery (many flash games are guilty of this). Something to consider when deciding whether to throttle your loops or not.
The answer by joshperry is pretty much what you want, but there are also a few ways about it. If you are using multiple threads, you have to also deal with locking etc. Depending on your game architecture that may / may not be a big deal. For example, do you do lots of locking, is there a lot of message passing between threads etc. If you are a traditional game you usually have a single main loop - I have a queue of CMD objects (runnable if you like, but can also be more event bus like in nature) that are executed continuously until the queue is empty. The thread then waits until it is signaled that a new cmd is in the queue. For most games this is usually enough. So the question then becomes how / when are cmds added. I use a timer/scheduler (also note the comments about java time resolution) to add a cmd to the main loop at the required frame rate. This has the advantage of also being kind to laptops etc. On startup you can also then benchmark the system to see how fast it is running, and then set an appropriate frame rate (ie. start with a supported base, then work to a max). Benchmarking or using user specified performance hints (ie. amount of rendering detail) can then be used by each type of cmd (ie. the render scence cmd / event looks at the performance settings for detail etc). (note - cmds dont' have to be runnable, they can be more like an event bus with listeners that are invoked on the main thread).
Also if a task wants to then use multi-thread/core's the handler for the cmd (if its an event type model - i personally like the event model - its easier to access the shared state info without needing global singletons) can then spawn multiple tasks (say using an existing thread pool - so the cost of new threads are not hit every cmd) and then use a barrier type class to wait for all the tasks to complete. This method usually makes locking easier, as each cmd (or system) usually has different locking requirements. Thus you can implement just the locking for that system and not have to worry about locking between sub systems - ie. for physics you can lock on bundles of objects in the game area, and each forked thread in the thread pool then worries only about its objects ie. thread1 handles objects1 to 20, thread2 objects 21-40 etc (this is just to illustrate the concept of how each cmd can implement a custom locking algorithm that works best for what it is doing, without having to worry about what other sub systems are doing with shared state data).
The important thing is to look at how and why you are using threads and locking etc.
For a game, probably not. Just make sure your game pauses when the switches tasks.
You would actually want to use Thread.yield() in this case. It is possible that one thread will run continuously, and not allow any other threads time to execute. Placing a yield call at the end of each iteration gives the scheduler a hint that it is time to allow other threads to run as well.