Почему этот простой апплет использует более 50% моего процессора? - PullRequest
1 голос
/ 07 апреля 2009

Я написал простой апплет для создания игр, и он уже использует> 50% моего процессора. Я на 3 ГГц P4 с 1,5 ГБ оперативной памяти, поэтому я знаю, что это не должно занимать слишком много.

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){}
        }
    }
}

Ответы [ 6 ]

8 голосов
/ 07 апреля 2009

Попробуйте заменить занятое ожидание на

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
   }
}

Это гарантирует, что время между кадрами будет не менее 16 мс . Если ваше время рендеринга меньше 16 мс, а другие потоки не загружают процессор, он будет работать со скоростью 60 кадров в секунду.

Ваше первоначальное решение будет обеспечивать минимум 16 мс, но оно должно опрашивать системное время снова и снова (которое использует ЦП), пока не пройдет необходимое количество времени.

Примечания:

5 голосов
/ 07 апреля 2009

Извините, что этот пост больше относится к типу "и для дополнительной информации ...", чем к прямому ответу, который, я думаю, был дан сейчас - я просто подумал, что было полезно не потерять вещи в комментариях.

Похоже, что этот поток показывает много (по общему признанию) неправильного понимания того, что на самом деле делают такие методы, как Thread.sleep () и Thread.yield (). Ранее я написал материал, который может заинтересовать людей, когда я попытался прояснить некоторые из этих вопросов: Thread.sleep () (включая график поведения при различных уровнях нагрузки), Thread.yield () и ... хотя это и не упоминалось здесь, людям может быть интересен мой взгляд на приоритеты потоков .

Между прочим, , как правило, не дает никаких преимуществ в использовании System.nanoTime () в этом случае: вы просто получите время, округленное до ближайшей миллисекунды в любом случае. Я бы избавил вас от неловких вычислений и потенциальных затрат времени на получение наносекундного времени (хотя последние тоже не так уж и плохи) и просто использовал бы хороший ole 'традиционный System.currentTimeMillis (). Если ваша нить проспала, просто в следующий раз компенсируйте, поспав меньше.

2 голосов
/ 07 апреля 2009

Вы заняты ожиданием, пока время не достигнет определенного порога. Однако уступка не означает, что ваш поток прекращает работу, если ни один другой поток не хочет времени ...

Если вы хотите подождать и сократить использование процессора, рассмотрите Thread.sleep

1 голос
/ 07 апреля 2009

Обратите внимание, что 1600000 нс = 1,6 мс, поэтому вы, вероятно, не спите столько, сколько ожидаете.

0 голосов
/ 07 апреля 2009

Разница между Thread.sleep и занятым ожиданием заключается в том, что, когда вы переводите поток в спящий режим, вы говорите компьютеру, что вам не нужно ничего делать в течение x секунд, и компьютер позволит другому процессу использовать это время ,

Однако, с занятым ожиданием, вы говорите своей машине постоянно запускать код цикла, даже если он ничего не делает.

0 голосов
/ 07 апреля 2009

Вероятно, вы видите только 50% из-за того, что Java не использует второе ядро ​​вашего процессора.

Ваш код будет выполнять сложение и сравнение так быстро, как процессор может их выполнить.

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

Используйте Thread.sleep (16) вместо замкнутого цикла while с большим количеством математики.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...