while loop或Thread.sleep()?

时间:2016-04-14 14:58:48

标签: java game-engine timing frame-rate thread-sleep

我正在使用Java编写游戏,我将FPS限制为60.我想出了两种不同的方法来获得相同的结果,但我想知道哪种方式更好/更清晰。或许你有不同的想法。

House

while(System.nanoTime() - thisFrame < fps_limit);

我的想法是 while循环影响CPU超过 Thread.sleep ,我是对的吗?

先谢谢你的帮助!

Dom

7 个答案:

答案 0 :(得分:2)

您有以下主要选项:

  1. while循环 - 这将消耗CPU周期,并且通常会实际停止系统,因为在循环时,其他线程无法运行(在单核机器上)。
  2. Thread.sleep() - 这可能有效,但您需要记住,不能保证等待指定的时间。
  3. DelayQueue - 更新。更好/准确的计时。
  4. ScheduledThreadPoolExecutor - 比DelayQueue更新。使用Thread Pool

答案 1 :(得分:0)

你是对的,虽然两者都实现了你想要做的事情,while循环会使处理器占用,耗费CPU时间。

相反,Thread.sleep()将处理器释放所述的时间。

所以,Thread.sleep()更好。

答案 2 :(得分:0)

我同意@ayush - while循环通常是阻塞函数,而线程更像是中断驱动或并行编程函数。我在Java上有点绿,但是你不能设置计时器而不是睡觉吗?

是的,看起来像在C ++中的Timer构造是可用的。看看这个:Timer in Java Thread

答案 3 :(得分:0)

已经发布的答案都很好 - 睡眠比循环更好。但是,您可以详细了解如何编写好的循环。如果您有兴趣,这是一个很好的资源:http://www.java-gaming.org/index.php?topic=24220.0

它涵盖了可变时间步和插值等主题,可用于使图形运行非常流畅。这解决了Thread.sleep在时间上没有100%准确的问题,以及如果你的游戏执行一些花费一些时间的计算,就会阻止你的图形显得生涩。

答案 4 :(得分:0)

你不应该同时使用它们。请查看ScheduledThreadPoolExecutor

的文档

特别是你正在看这个功能

ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long initialDelay, long period, TimeUnit unit)

答案 5 :(得分:0)

我会做什么(伪代码)。

//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
}

通过这种方式,您可以使用变量轻松限制fps,而不需要阻止其他线程。

正如OldCurmudgeon所说,thread.sleep dosnt会阻止java中的其他线程并使处理器时间可用。

  

Thread.sleep导致当前线程暂停执行a   指定期间。这是一种有效的处理器时间   可用于应用程序或其他应用程序的其他线程   可能正在计算机系统上运行

此外,您可以将{time}作为deltatime传递给dostuff方法,以便游戏在所有设备上运行相同(速度相同)。

答案 6 :(得分:-1)

while循环将使用CPU资源,只有当你的avg.waiting时间非常短并且期望精确时它才有用。

如果没有预期的精度,

Thread.sleep()就可以了,因为线程唤醒后CPU优先级会发生变化,可能会立即调度也可能不立即运行,也不应该使用它像这样

while(! canContinue()) {
   Thread.sleep(1000);
}

对于上面的情况,如果你想暂停当前线程并等待另一个线程处理某些事情然后通知当前线程,那么最好使用 wait()/ notify()这些情况。线程继续。

您可以阅读的一些参考资料,

http://tutorials.jenkov.com/java-concurrency/thread-signaling.html

http://www.jsresources.org/faq_performance.html#thread_sleep