1

我写了一个简单的小程序作为制作游戏的基础,它已经占用了我 50% 以上的 CPU。我在一个 3ghz P4 和 1.5gb 内存上,所以我知道它不应该占用那么多。

import java.awt.*;
import java.applet.*;

public class applettest extends Applet implements Runnable {

    long lastFrame;

    public void init() { 
        (new Thread(this)).start();
    }

    public void paint(Graphics g) {
        g.drawString("Welcome to Java!!", 50, 60 ); 
    }

    public void run() { 
        while(true) {
            // code here
            repaint();

            try{
                // wait 16 milliseconds to cap frame rate to 60 fps
                while (System.nanoTime() < lastFrame + 160000000)       {
                    Thread.yield();
                }

                lastFrame = System.nanoTime();
            }

            catch(Exception e){}
        }
    }
}
4

6 回答 6

8

尝试用_

lastFrame = System.currentTimeMillis();

while(true) 
{
   repaint();

   long msSleep = 16 - (System.currentTimeMillis() - lastFrame);
   lastFrame = System.currentTimeMillis();

   if(nsToSleep > 0)
   {
      Thread.sleep(msSleep);
   }
   else
   {
      Thread.yield();  // Only necessary if you want to guarantee that
                       // the thread yields the CPU between every frame
   }
}

这将保证帧之间的时间至少为 16ms。如果您的渲染时间小于 16 毫秒,并且没有任何其他线程占用 CPU,它将以 60 fps 运行。

您的原始解决方案将强制执行最少 16 毫秒,但它必须不断轮询系统时间(使用 CPU),直到经过必要的时间。

笔记:

于 2009-04-06T22:11:02.147 回答
5

抱歉,这篇文章更多的是“以及更多信息......”类型而不是直接答案,我认为现在已经给出了 - 我只是认为不要让评论中的东西丢失是有帮助的。

这个线程似乎对 Thread.sleep() 和 Thread.yield() 之类的方法实际上做了很多(公认的典型)误解。我之前写过一些人们可能会觉得有趣的材料,我试图澄清其中一些问题:Thread.sleep()(包括不同负载水平下的行为图)、Thread.yield()和- - 与此相关,虽然这里没有提到,但人们可能会对我对线程优先级的看法感兴趣。

顺便说一句,在这种情况下使用 System.nanoTime() 通常没有任何好处:无论如何,您只会得到一个四舍五入到最接近毫秒的时间。我会为你自己节省检索纳秒时钟时间的笨拙计算和潜在开销(尽管后者也不是那么糟糕),只需使用良好的 ole' 传统 System.currentTimeMillis()。如果你的线程睡过头了,下次只需少睡一点就可以了。

于 2009-04-07T05:45:36.343 回答
2

您正在忙着等待,直到时间达到某个阈值。但是,屈服并不意味着如果没有其他线程想要时间,您的线程就会停止运行......

如果您想等待并减少 CPU 使用,请考虑 Thread.sleep

于 2009-04-06T22:12:34.293 回答
1

请注意,1600000 ns = 1.6 ms,因此您的睡眠时间可能没有预期的那么长。

于 2009-04-06T22:35:30.900 回答
0

Thread.sleep 和忙等待之间的区别在于,当您让线程进入睡眠状态时,您是在告诉计算机您在 x 秒内不需要做任何事情,而 pc 将让其他进程使用该时间。

然而,在忙碌的等待中,你告诉你的机器不断地运行循环代码,即使它并没有真正完成任何事情。

于 2009-04-07T05:26:36.747 回答
-2

由于 java 没有使用 CPU 的第二个内核,您可能只看到 50%。

您的代码将尽可能快地进行加法和比较。

// wait 16 milliseconds to cap frame rate to 60 fps
while (System.nanoTime() < lastFrame + 16000000)        {
  Thread.yield();
}

使用 Thread.sleep(16) 代替带有大量数学运算的紧密 while 循环。

于 2009-04-06T22:11:43.190 回答