# Thread runs faster on a faster processor… how to control Thread speed

I have a thread that uses TimeUnit.MILLISECONDS.sleep(5);

Problem is when I load my app on a faster phone say with a snapdragon, it runs at lightning speed.

Is there a way to control this speed so processor speed is not an attributing factor?

Thanks!

He'res the class I wrote for this purpose. Use it by first calling start() and then sleepRequiredTime() in your gameloop. call getTimeSinceLastSleep() for elapsed time.

runsPrSecondHint will dictate your wanted FPS. I'm not sure this solution is perfect though, so any input from others is welcome.

package com.ngame.spacegame.utils;

private int m_runsPrSecondHint;
private float m_maxAllowedSleepTime;
private boolean m_running;

private long m_startTime = 0;
private long m_lastSleepTime = 0;

private int[] m_lastRuntimes;
private int m_runtimeToWriteToIndex = 0;
private int m_averageSleepTime = 0;
private int m_timeSinceLastSleep = 0;

private static final int AVERAGE_POOL = 10;

public ThreadSleepManager( int runsPrSecondHint ) {
m_runsPrSecondHint = runsPrSecondHint;

m_maxAllowedSleepTime = 1000.0f / m_runsPrSecondHint;
initLastRuntimes();
}

private void initLastRuntimes() {
m_lastRuntimes = new int[AVERAGE_POOL];
for ( int i : m_lastRuntimes ) {
m_lastRuntimes[ i ] = (int)m_maxAllowedSleepTime;
}
}

public int getTimeSinceLastSleep() {
return m_timeSinceLastSleep;
}

public int getAverageSleepTime() {
return m_averageSleepTime;
}

public void start() {
m_startTime = System.currentTimeMillis();
m_lastSleepTime = m_startTime;
}

/**
* Sleeps an optimal amount of time for trying
* to have the current thread calling run at m_runsPrSecondHint
*/
public void sleepRequiredTime() {
assert( m_running == true );
long currentTime = System.currentTimeMillis();
m_timeSinceLastSleep = (int) (currentTime - m_lastSleepTime);

// Update data used for average sleep time calculation
m_lastRuntimes[ m_runtimeToWriteToIndex ] = m_timeSinceLastSleep;
m_runtimeToWriteToIndex = ( m_runtimeToWriteToIndex + 1 ) % AVERAGE_POOL;

// Sleep long enough for the average time since last sleep to stay as close as
// possible to m_maxAllowedSleepTime
m_averageSleepTime = calcAverageTimeSinceLastSleep();

int timeToSleep = (int) (m_maxAllowedSleepTime - m_averageSleepTime);
if( timeToSleep > 0 ) {
try {
}
catch( InterruptedException e ) {

}
}

m_lastSleepTime = currentTime;
}

private int calcAverageTimeSinceLastSleep() {
int sum_sleep_time = 0;

for ( int runtime : m_lastRuntimes ) {
sum_sleep_time += runtime;
}

return sum_sleep_time / m_lastRuntimes.length;
}


}

• That being said, I would probably fix my time step if I were you. Even though this code here tries to find a smart amount of time to sleep based on the average calculation times of previous frames, it seems to stutter now and again. You should accept fix your timestep as answer instead =) – Nailer Oct 15 '10 at 8:37

You need to Fix Your Timestep!

http://gafferongames.com/game-physics/fix-your-timestep/

• Favorite just for this link. Pesky black box physics. – David Young Oct 14 '10 at 18:55
• The OP should not be using a fixed sleep time when the rest of the processing can take an unknown amount of time. – dash-tom-bang Oct 14 '10 at 19:11
• Please read the article fully then. He addresses this issue when he talks about "The Spiral of Death". – AttackingHobo Oct 14 '10 at 19:19
• yes, so I was commenting that the simple takeaway for the OP is that ... Fixed timestep is the One True Path, even if GoG takes a lot of words to get to the point. – dash-tom-bang Oct 16 '10 at 0:52

Instead of sleeping to regulate game speed, use the time elapsed per frame to give everything a consistent speed.

myObject.Move(elapsedTime*moveSpeed,0,0);


Something to that effect. No matter what speed the processor runs at or the framerate, the object would always move at the same speed. Make sure any movement or rotation that requires a specific speed uses the same idea.

• how do I get elapsed time – Adam Coburn Oct 14 '10 at 13:49
• Depends on what you're using. If it's a game engine, check the documentation - there may be something built in. If not, you have to calculate it yourself using whatever time functions are available on your platform. – beezir Oct 14 '10 at 14:58
• Do not use this exact method if you want physics that react the same way each time a simulation is run. The physics will look almost the same, but there will be small errors that accumulate and through through chaos theory, the physics will be much different each time. What happens if the game lags for 2 seconds? What about 10 seconds? Stuff might tunnel through walls. Your character might fall through the floors. Springs could "explode". I posted a better answer. – AttackingHobo Oct 14 '10 at 16:33
• Everything gets harder with a variable timestep, so while it is an option it is not a great one (IMO). – dash-tom-bang Oct 14 '10 at 19:09
• Agreed, AttackingHobo's link could be considered the canonical reference for managing your timestep. – jpaver Oct 14 '10 at 19:51