while 循环还是 Thread.sleep()?
while loop or Thread.sleep()?
我正在 Java 编写游戏,我将 FPS 限制为 60。我想出了 2 种不同的方法来获得相同的结果,但我想知道其中哪一种是 better/cleaner 的方法。或者你有不同的想法。
while(System.nanoTime() - thisFrame < fps_limit);
或
Thread.sleep(sleepingTime);
我的想法是 while 循环 比 Thread.sleep 对 CPU 的影响更大,对吗? ?
在此先感谢您的帮助!
Dom
你是对的,虽然两者都实现了你想要做的事情,while
循环将保持处理器被占用,消耗 CPU 时间。
相比之下,Thread.sleep()
释放处理器达到上述时间。
所以,Thread.sleep() 更好。
我同意@ayush - 虽然循环通常是阻塞函数,而线程更像是中断驱动或并行编程函数。我对 Java 有点不适应,但你能不能设置一个定时器而不是休眠?
是的,看起来像 C++ 中的 Timer 结构是可用的。看看这个:Timer in Java Thread
已经发布的两个答案都很好 - 睡眠比循环好。但是,您可以更详细地了解如何编写良好的循环。如果您有兴趣,这里有一个很好的资源:http://www.java-gaming.org/index.php?topic=24220.0
它涵盖了可变时间步长和插值等主题,可用于使您的图形运行极其流畅。这解决了 Thread.sleep 的时间不是 100% 准确的问题,并且如果您的游戏执行某些计算需要一些时间,则可以防止您的图形出现抖动。
您有以下主要选择:
- While loop - 这将消耗 CPU 个周期,并且通常实际上会停止系统,因为当你在循环时,其他线程不能 运行(在单核机器)。
Thread.sleep()
- 这可能有效,但您需要记住,不能保证等待指定的时间。
- DelayQueue - 更新。 Better/accurate 计时。
- ScheduledThreadPoolExecutor - 仍然比
DelayQueue
更新。使用 Thread Pool
.
你不应该使用它们。请查看 ScheduledThreadPoolExecutor
的文档
特别是你在看这个函数
ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long initialDelay, long period, TimeUnit unit)
我会做什么(伪代码)。
//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 不阻塞 java 中的其他线程并使处理器时间可用。
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
您还可以将过去的时间作为 deltatime 传递给 dostuff 方法,这样游戏在所有设备上运行相同(相同速度)。
while loop 将使用 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
我正在 Java 编写游戏,我将 FPS 限制为 60。我想出了 2 种不同的方法来获得相同的结果,但我想知道其中哪一种是 better/cleaner 的方法。或者你有不同的想法。
while(System.nanoTime() - thisFrame < fps_limit);
或
Thread.sleep(sleepingTime);
我的想法是 while 循环 比 Thread.sleep 对 CPU 的影响更大,对吗? ?
在此先感谢您的帮助!
Dom
你是对的,虽然两者都实现了你想要做的事情,while
循环将保持处理器被占用,消耗 CPU 时间。
相比之下,Thread.sleep()
释放处理器达到上述时间。
所以,Thread.sleep() 更好。
我同意@ayush - 虽然循环通常是阻塞函数,而线程更像是中断驱动或并行编程函数。我对 Java 有点不适应,但你能不能设置一个定时器而不是休眠?
是的,看起来像 C++ 中的 Timer 结构是可用的。看看这个:Timer in Java Thread
已经发布的两个答案都很好 - 睡眠比循环好。但是,您可以更详细地了解如何编写良好的循环。如果您有兴趣,这里有一个很好的资源:http://www.java-gaming.org/index.php?topic=24220.0
它涵盖了可变时间步长和插值等主题,可用于使您的图形运行极其流畅。这解决了 Thread.sleep 的时间不是 100% 准确的问题,并且如果您的游戏执行某些计算需要一些时间,则可以防止您的图形出现抖动。
您有以下主要选择:
- While loop - 这将消耗 CPU 个周期,并且通常实际上会停止系统,因为当你在循环时,其他线程不能 运行(在单核机器)。
Thread.sleep()
- 这可能有效,但您需要记住,不能保证等待指定的时间。- DelayQueue - 更新。 Better/accurate 计时。
- ScheduledThreadPoolExecutor - 仍然比
DelayQueue
更新。使用Thread Pool
.
你不应该使用它们。请查看 ScheduledThreadPoolExecutor
的文档特别是你在看这个函数
ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long initialDelay, long period, TimeUnit unit)
我会做什么(伪代码)。
//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 不阻塞 java 中的其他线程并使处理器时间可用。
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
您还可以将过去的时间作为 deltatime 传递给 dostuff 方法,这样游戏在所有设备上运行相同(相同速度)。
while loop 将使用 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