demo using 100% CPU

Hi there! I have coded a small demo, but it is using 100% of the CPU. How can I avoid this? Below is the run() method

I am running on win2000 and FPS=60. Is Thread.yield() not working or I missed something?


final int FRAME_LENGTH = 1000 / FPS;
            long startTime = System.currentTimeMillis();
            int frameCount = 0;
            System.out.println(FRAME_LENGTH);
            while (!this.quit) {
                  this.paint(this.getGraphics());
                  frameCount++;
                  while ((System.currentTimeMillis() - startTime) / FRAME_LENGTH < frameCount) {
                        System.out.println("fc=" + frameCount + " elapsed="
                                    + ((System.currentTimeMillis() - startTime) * 1000)
                                    + " fps=" + (float) frameCount
                                    / (System.currentTimeMillis() - startTime) * 1000);
                        frameCount = 0;
                        Thread.yield();
                  }
            }

yield() changes threads. Thus, if your thread is the only one that is ready to run, you’ll be back immediately.

Thread.sleep()?

That’s right. And there’s nothing intrinsically wrong with using 100% CPU if you’re being kind to other processes by yielding.

Cas :slight_smile:

I have re-designed my demo and in the main run() loop of the demo as follows:


            int delayPerFrame = 1000/60;
            PreciseTimer preciseTimer = new PreciseTimer(delayPerFrame);             
            while (!this.quit) {
                  preciseTimer.start();
                  this.paint(this.getGraphics());
                  try{
                        Thread.sleep(delayPerFrame-preciseTimer.getMilliSeconds());
                  }catch(Exception e) {}
                  preciseTimer.endTimer();
            }


Here is the code for PreciseTimer:


      private class PreciseTimer implements Runnable{

            private Thread preciseTimerThread = new Thread(this, "precise");
            private long milliSeconds=0;
            private boolean endTimer = false;
            private int maxMilliSeconds=0;

            public PreciseTimer()
            {
            preciseTimerThread.start(); 
            }

            public PreciseTimer(int max)
            {
            maxMilliSeconds=max;
            preciseTimerThread.start(); 
            }

            public void start(){
            milliSeconds=0;
            }

            public long getMilliSeconds(){
            if (milliSeconds>maxMilliSeconds){milliSeconds=maxMilliSeconds;}
            return (milliSeconds);
            }

            public void endTimer(){
            endTimer=true;
            }



            public void run(){
            while (!endTimer){ 
            milliSeconds++;
            try{preciseTimerThread.sleep(1);}catch(java.lang.InterruptedException e){}
            }

            }

            }

Now the question: What about this code? Is this valid code to lock my demo at 60fps?

Is this valid code to lock my demo at 60fps?

Theoretically, yes.

However, sleep is only accurate down to ~5msec (on windows at least).

If you need accurate throtteling and you still want to use sleep you can check if the time to waste is >5msec and sleep then.

Eg something like this (change accordingly):


public static void sync2b(long fps) //hz+1
{
      long gapTo = Sys.getTimerResolution() / fps + timeThen;
      timeNow = Sys.getTime();

      while(gapTo > timeNow+timeLate)
      {
            if(gapTo > timeNow+timeLate+5000L)
                  Thread.sleep(5);
            else
                  Thread.yield();
            timeNow = Sys.getTime();
      }

      if(gapTo<timeNow)
            timeLate = timeNow-gapTo;
      else
            timeLate = 0;

      timeThen = timeNow;
}