csg*_*000 2 java multithreading sleep loops
我只有一个程序,用于在它自己的线程中执行此操作:
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
基本上我总是在这样循环时被教导睡觉,所以我做了,我的程序睡眠至少5毫秒,或者它可以睡觉的最多时间而不超过限制(1/30秒).但我正在四处看书,睡觉听起来不是很好.
从他的说法来看,如果它太接近睡眠下限,我的程序甚至都不会睡觉,等等.当system.printing时间的变化时,变化的范围大约是.31508 - .03475,这对我来说真的很好,因为我的程序会导致不准确.
话虽这么说,我还能做些什么呢?我正在考虑添加类似这样的东西,而不是尝试{Sleep}:
long waitTill = (long) (System.nanoTime()+lastTime/1000000000f),
now = System.nanoTime();
while(now < waitTill){
now = System.nanoTime();
}
Run Code Online (Sandbox Code Playgroud)
但是我的线程不会占用相同数量的处理器时间吗?我认为重点是阻止我们的线程占用更多的处理器,而不是实际需要的...
那么,我应该使用睡眠(最小睡眠时间更长?),我应该使用我的替代方案,我应该使用其他替代方案,还是应该让我的程序以无限制的速度循环?即使我考虑到睡眠不准确,我编程也很差吗?
谢谢您的帮助!
编辑: 所以,定时器已被推荐,但我明白,如果我的任务没有在Timer再次调用之前完成,那么我会遇到问题.这对我的计划来说是一个明确的问题.我觉得我已经通过使用delta处理了Thread.sleep()的问题,所以,Thread.sleep()会像以前一样更好吗?
要解决此问题,您需要重新考虑您的设计.基本上你正在做的是定期安排工作.运行/静止/睡眠模式有效,但正如您的研究发现的不是最佳解决方案.
现代语言具有"任务运行"模式,允许编程环境/ OS更好地管理任务的执行.
在Java中有java.util.timer以及java.util.timertask.使用任务运行模式,您可以创建任务,并将其安排为以特定间隔运行.
通过取消定时器而不是设置布尔标志,定时器还为您提供了一种更简洁的方法来停止执行循环.
来自评论:
有一些人应该注意的问题.如果您的任务是任务运行时间超过计划间隔的任务,则可以在上一个任务仍在执行时运行另一个任务.一些解决方案:
另一个常见问题是计划的计时器通常被实现为尽力而为.也就是说,OS/Framework尝试按计划运行任务,但不保证任务将在指定的时间间隔内完全执行.因此,如果您的任务需要严格的确定性调度,您可能需要更接近操作系统/硬件解决方案.