12

I want to have a class that changes its own private variables every 2 seconds. I know that if I do something like

import java.util.Timer;
//...
Timer timer;
//...
timer.schedule(new ChangeSomething(), 2000);

It will execute ChangeSomething() after 2 seconds, is there a way to tell it to do something every 2 seconds, or, If I put inside ChangeSomething()

    timer.schedule(new ChangeSomething(), 2000);

will it work?

On a side-note, what does timer.cancel() exactly do?

SIMEL
  • 8,745
  • 28
  • 84
  • 130

4 Answers4

13

Use timer.scheduleAtFixedRate() to schedule it to recur every two seconds:

Schedules the specified task for repeated fixed-rate execution, beginning at the specified time. Subsequent executions take place at approximately regular intervals, separated by the specified period.

From the javadoc for Timer.cancel():

Terminates this timer, discarding any currently scheduled tasks. Does not interfere with a currently executing task (if it exists). Once a timer has been terminated, its execution thread terminates gracefully, and no more tasks may be scheduled on it.

EDIT:

Relating to internal execution thread for a Timer that executes a single task once:

After the last live reference to a Timer object goes away and all outstanding tasks have completed execution, the timer's task execution thread terminates gracefully (and becomes subject to garbage collection). However, this can take arbitrarily long to occur. By default, the task execution thread does not run as a daemon thread, so it is capable of keeping an application from terminating. If a caller wants to terminate a timer's task execution thread rapidly, the caller should invoke the timer's cancel method.

hmjd
  • 120,187
  • 20
  • 207
  • 252
  • What I don't understand about timer.cancel(), is whether it's required to do after I make a task that is was scheduled only once to make sure that it'll not be done again or not? – SIMEL Jan 29 '12 at 13:16
  • The Javadoc for `Timer` indicates this is not required and the timer's exeecution thread will terminate. However, it does specifically state that this can take an arbitrarily long time and `cancel()` can used to terminate it quicker. (Pasted relevant paragraph from Javadoc into answer). – hmjd Jan 29 '12 at 13:22
7

You will need to call to a different scheduling method of Timer, called scheduleAtFixedRate(...) which can get 3 parameters. The first 2 are identical to those of schedule you've used, while The third parameter indicates a period time in milliseconds between successive task executions.

import java.util.Timer;
//...
Timer timer;
//...
timer.scheduleAtFixedRate(new ChangeSomething(), 2000, 2000);

You can check the java pai doc for this method here: http://docs.oracle.com/javase/6/docs/api/java/util/Timer.html#scheduleAtFixedRate(java.util.TimerTask, java.util.Date, long)

6

Here is an example

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class Test extends TimerTask {
   private int age;

   public Test() {
       Timer timer = new Timer();
       timer.scheduleAtFixedRate(this, new Date(), 2000);
   }

   /**
    * Implements TimerTask's abstract run method.
    */
    public void run(){
      //toy implementation
      System.out.print("Changing Data ... before change age is "+age+" ");
      changeAge();
      System.out.println("after change age is "+age);

    }


   private void changeAge() {
      age = (int)Math.round(Math.random()*1000);
   }

  public static void main(String[] args) {
          new Test();
  }

}

barnardh
  • 736
  • 1
  • 6
  • 8
0

To be more precise here: ChangeSomething() is the constructor of your ChangeSomething class. The constructor will be executed immediately when you pass the ChangeSomething instace object to the timer, not after 2 seconds. It's that object's run() method will be triggered after 2 seconds.

To execute that run() method repeatedly all 2 seconds, use schedule(TimerTask task, long delay, long period)

Jan
  • 2,498
  • 1
  • 15
  • 6