为什么这个简单的applet使用了超过50%的CPU?

Wil*_*iam 1 java cpu applet

我写了一个简单的applet作为基础制作游戏,它已经占用了我50%以上的CPU.我正在使用1.5gb ram的3ghz P4,所以我知道它不应该占用太多.

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){}
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Dan*_*ant 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
   }
}
Run Code Online (Sandbox Code Playgroud)

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

您的原始解决方案将强制执行最小16ms,但它必须反复轮询系统时间(使用CPU),直到经过必要的时间.

笔记:


Nei*_*fey 5

对不起,这篇文章更多的是"和更多的信息.​​.."类型,而不是直接的答案,我认为现在已经给出了 - 我只是认为不要让评论中的内容丢失是有帮助的.

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

顺便提一下,在这种情况下使用System.nanoTime()通常没有任何好处:在任何情况下,你只需要将时间四舍五入到最接近的毫秒.我将保存您的笨拙计算和检索纳秒时钟时间的潜在开销(虽然后者也不是那么糟糕)并且只使用好的传统System.currentTimeMillis().如果您的线程处于睡眠状态,只需通过较少的睡眠进行补偿.