tags:

views:

652

answers:

6

Am I doing something really stupid here? I am trying to execute a method every minute or so, forever, or until I stop the program.

 while(true) {
  this.doSomethingPeriodically();
  Calendar now = Calendar.getInstance();
  int minutes = now.get(Calendar.MINUTE);
  int resume = minutes + 1;
  while (now.get(Calendar.MINUTE) < resume) {
   // waiting for a minute
  }
 }
+11  A: 

This code will never leave the loop. It's an endless loop, since the Calendar instance refered to by now won't change.

Also, what you try to do here is implement busy waiting which is a very bad idea (it uses CPU time doing nothing interesting).

The correct way to sleep is to use Thread.sleep().

Joachim Sauer
So, if I had a new Calendar instance, it'd work? But I should use sleep() anyway, huh?
Sam McAfee
Yes to both ;-) If you assigned a new Calendar instance to now inside the loop then it would work (provided you don't enter the loop in minute 59 of the hour ;-)), but you should use sleep() instead anyway.
Joachim Sauer
Understood. I would reinventing the wheel, and making it square instead of round, so to speak. Thanks!
Sam McAfee
At the risk of being pedantic, Thread.sleep() will pause your thread for *at least* a minute (and not necessarily exactly one minute).
Tuzo
Using sleep, you just leaves the "CPU" and became available from the "stop point + 1 line" after the sleep time.In teh case of that loop, your code only work inside that loop. Use java.util.Time and java.util.TimerTask for a clear code.
apast
+1  A: 

It would be better to use a Timer or at least use a sleep.

tster
+4  A: 

Try using the Timer class instead. It's meant for this sort of thing. http://www.javapractices.com/topic/TopicAction.do?Id=54 http://java.sun.com/j2se/1.4.2/docs/api/java/util/Timer.html

Edit: I just read that there's a newer replacement for Timer: ExecutorService. I've never used it, but it seems to have some advantages. http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ExecutorService.html http://stackoverflow.com/questions/409932/java-timer-vs-executorservice

Scott Saunders
+1 - I forgot about the Timer class.
James Black
+3  A: 

Try using sleep isntead, as it won't cause the processor to continue working on the thread:

Thread.sleep()

    while(true) {
            this.doSomethingPeriodically();
            Thread.sleep(60000);
    }
Marius
You should not extend Thread (implement Runnable instead) and you should not reference static methods (such as Thread.sleep()) via a reference.
Joachim Sauer
I would also say that it is generally a better idea to use a short sleep time and rather repeat it and check if we should stop.
Svish
@Svish, that's what `InterruptedException` is for.
gustafc
+1  A: 

What you're trying to do here is called busy waiting. You are unnecessarily using huge amounts of CPU time (and you would even be using unnecessary memory if you fixed your bug and created a new Calendar instance in each loop).

What you actually want is the method Thread.sleep(), it is pretty well explained in a tutorial on sun.com.

soulmerge
+4  A: 

Hi,

the simplest way for execute tasks repeteadly in java is the java.util.TimerTask and java.util.Timer api.

A simple code is:

public class PrinterTimerTask extends java.util.TimerTask {
  @Override
  public void run() {
    System.out.println( 'Current time is: ' + System.nanoTime() );
  }

  public static void main(String[] args) {
    long delay = 0;
    long period = 60000;
    java.util.Timer timer = new java.util.Timer(threadName);
    PrinterTimerTask task = new PrinterTimerTask();
    timer = new Timer("SomeThreadNameForProfiler");
    timer.schedule( task, delay, period );
  }
}

Variables: task - task to be scheduled. delay - delay in milliseconds before task is to be executed. period - time in milliseconds between successive task executions.

More info: Timer and TimerTask javadoc: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Timer.html http://java.sun.com/j2se/1.5.0/docs/api/java/util/TimerTask.html

Another example: http://www.javapractices.com/topic/TopicAction.do?Id=54

[]'s,

And Past

apast