我试图在一秒内执行N次指令或功能N次。 我怎么能在java中这样做? 如下......
//in one second
while(N)
{
printf(".........");
int x=0;
printf("The value of x is ");
}
但问题实际上变得更深了..我试图手动绘制像素,我想要每秒旋转效果没有...所以基本上,它必须执行N次一秒钟(但这是无限制的) )
提前致谢
答案 0 :(得分:5)
你永远无法确定它每秒会发生N次,但它是这样的:
long taskTime = 0;
long sleepTime = 1000/N;
while (true) {
taskTime = System.currentTimeMillis();
//do something
taskTime = System.currentTimeMillis()-taskTime;
if (sleepTime-taskTime > 0 ) {
Thread.sleep(sleepTime-taskTime);
}
}
答案 1 :(得分:5)
我会翻转这个问题:不要在一秒钟内将循环限制为N次。相反,处理N个工作单元在所需时间内均匀分布。
也就是说,计算自开始(或以前的工作)后经过的时间,将其插入工作率,并且做了那么多工作(开始/上一次的因素和已经完成的工作量)。这是许多游戏/动画引擎的基础 - "delta time"。
然后在每个循环结束时调用yield
以“变得更好” - 或者更确切地说,防止吃掉99%以上的CPU使用量!产量本身具有最小分辨率 1 ,但效果通常是足够的,特别是在适当插值时。
因为使用了插值方法,所以这应该适用于所有N(可以在指定的时间内运行),即使这意味着每个循环执行更多N.对于小N,也可能不会对任何特定的循环进行任何工作,但yield
使得这种“额外繁忙的循环”在CPU利用率 2 方面便宜。
这是一些伪代码,用于在一秒内打印出20“x”s,其中now
返回小数秒:
rate = 20 // per second - "N times per second"
done = 0
goal = 1 * rate // same as rate for 1 second
start = now()
while done < goal:
target = floor((now() - start) * rate)
work = (target - done) // work might be 0, that's okay
for 0 upto work:
print("x")
done += work
yield()
在这种情况下,由于恒定速率公式,很容易插入开始时间。使用基于自上次工作(或循环)以来的时间的“增量时间”是相似的,并且在没有离散公式时是合适的,但是稍微复杂并且可能导致细微的漂移误差。
1 实际 sleep/yield
的时间分辨率取决于实现,因系统而异。例如,它的范围可能低至1ms on Linux to 10-15ms on windows。
2 在处理时间增量的 之外,根据Dariusz Wawer的回答,可以改变sleep
期。但是,这会增加复杂性,简单的yield
通常就足够了。
答案 2 :(得分:1)
很难与所提出的解决方案相提并论。而不是计算迭代之间的差距,计算下一次迭代应该执行的绝对时间。这更准确,因为迭代不依赖于以前的迭代。
long startTime = System.currentTimeMillis();
long msPerIteration = 1000000/iterationsPerSecond;
long i=0;
while (true) {
// do stuff
long msWaiting = startTime + (msPerIteration * ++i) - System.currentTimeMillis();
if (msWaiting > 0)
Thread.sleep(msWaiting);
}
答案 3 :(得分:1)
我今天必须写一个游戏循环。我使用了一个溢出变量,以确保如果先前的跳动太快,下一个跳动将等待更长的时间。每次滴答都会消除一半的溢出,并用它来影响帧时间。
new Thread() {
public void run() {
long overflow = 0; // The greater the overflow, the slower the game had calculated the last tick, and the shorter this tick's wait needs to be
long lastStartTime = System.nanoTime();
while(true) {
long startTime = System.nanoTime();
overflow += (startTime - lastStartTime) - 16666667; // 16.67 milliseconds = 60 fps
tick();
long endTime = System.nanoTime();
long waitTime = 16666667 - (endTime - startTime) - overflow / 2;
try {
Thread.sleep(waitTime / 1000000, (int) (waitTime % 1000000));
} catch (InterruptedException e) {
e.printStackTrace();
}
overflow /= 2; // Do not remove all overflow at once to prevent oscillation of ticktime
lastStartTime = startTime;
}
}
}.start();
答案 4 :(得分:0)
将循环更改为while(true)
。
检查while
循环前的时间(以毫秒为单位)。在while
循环结束时,以毫秒为单位获取时间,并查看是否已经传递了1000个时间。如果是break
。
答案 5 :(得分:0)
伪代码:
Create Timer t;
t.Start;
int counter = N;
While ((t.Elapsedtime < 1 Second) AND (N > 0))
{
call your_function();
N--;
}
your_function()
{
printf(".........");
int x=0;
printf("The value of x is ");
}
答案 6 :(得分:0)
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start <= 1000) {
// Your code goes here
}
所有注意事项是您的代码将循环1000毫秒。它完成的次数是不确定的,每次运行都可能有所不同。