我只有一个程序曾经在自己的线程中执行此操作:
public void run(){
long lastTime = System.nanoTime();
float lastSleep = 0;
//Everything is in seconds.
while(running){
float delta = (System.nanoTime()-lastTime)/1000000000f;
lastTime = System.nanoTime();
manager.update(delta);
panel.repaint();
lastSleep = Math.max(maxTicSpeed-(delta-lastSleep),5/1000f);
try{
Thread.sleep((long) Math.round(lastSleep*1000));
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
基本上,总是这样循环学习 sleep ,所以我做到了,我的程序至少 sleep 了5毫秒,或者它在不超过限制的情况下最多可以 sleep 的时间(1/30秒)。但是我正在四处看书,而且 sleep 听起来并不好。
http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx
从他的话看来,如果我的程序太接近 sleep 下限等,我的程序甚至不会休眠。系统打印时间更改时,更改范围大约为.31508-.03475,这对我来说确实足够,因为我的程序考虑到了不准确性。
话虽这么说,我该怎么办呢?我正在考虑添加这样的内容,而不是try {Sleep}:
long waitTill = (long) (System.nanoTime()+lastTime/1000000000f),
now = System.nanoTime();
while(now < waitTill){
now = System.nanoTime();
}
但是我的线程会不会仍然占用相同数量的处理器时间?我认为关键是要阻止我们的线程占用过多的处理器,而不是实际需要的。
因此,我应该使用sleep(具有更长的最小 sleep 时间吗?),应该使用我的替代方法,还是应该使用其他替代方法,还是让我的程序以不受限制的速度循环?即使我解释了 sleep 不正确,我的编程能力还是很差吗?
谢谢您的帮助!
编辑:
因此,建议使用Timers,但是我知道,如果在Timer再次调用之前我的任务没有完成,那么我会遇到问题。这是我程序的确定关注点。我觉得我已经通过使用增量解决了Thread.sleep()的问题,所以,像以前一样Thread.sleep()会更好吗?
最佳答案
为了解决此问题,您将需要重新考虑您的设计。本质上,您正在做的是按定期计划的时间间隔进行工作。运行/同时运行/ sleep 模式有效,但是您的研究发现并非最佳解决方案。
现代语言具有“任务运行”模式,该模式允许编程环境/OS更好地管理任务的执行。
在Java中,有java.util.timer和java.util.timertask。使用任务运行模式,您可以创建任务,并将其计划为以一定间隔运行。
计时器还可以通过取消计时器(而不是设置 boolean 标志)来提供一种更干净的方式来停止执行循环。
从评论:
应该注意几个问题。如果您的任务是某个任务的运行时间可能超过计划的时间间隔,则有可能在上一个任务仍在执行时运行另一个任务。一些解决方案:
另一个常见的问题是计划的计时器通常是尽力而为的。也就是说,OS/Framework尝试按计划运行任务,但不保证任务将完全按照指定的间隔执行。因此,如果您的任务需要严格的确定性计划,则可能需要更接近操作系统/硬件的解决方案。