14

How can I change period of Timer at runtime?

    Timer timer = new Timer();

    timer.scheduleAtFixedRate(new TimerTask() {
        public void run() {

             // read new period
             period = getPeriod();

             doSomething();

        }
    }, 0, period);
VextoR
  • 5,087
  • 22
  • 74
  • 109
  • unfortunately, I believe you'll have to schedule a new timer with the new period. anyway, you should be using a `ScheduledExecutorService`. – mre Jun 29 '11 at 12:03
  • maybe use this: scheduleAtFixedRate(TimerTask task, Date firstTime, long period); – peshkira Jun 29 '11 at 12:04
  • @peshkira, OP already knows about that method, but he's asking if it's possible to alter the period at runtime, which isn't possible. – mre Jun 29 '11 at 12:06

4 Answers4

8

You cannot do this directly, but you can cancel the tasks on the Timer and reschedule them with the desired period.

There is no getPeriod method.

Mathias Schwarz
  • 7,099
  • 23
  • 28
  • 7
    You cannot reschedule an existing TimerTask. Once cancelled, it will never run again. You'll need to create a new TimerTask instance. – Spycho Aug 03 '11 at 14:47
4

You can do it like this:

private int period= 1000; // ms

private void startTimer() {
    Timer timer = new Timer();
    timer.schedule(new TimerTask() {
        public void run() {
            // do something...
            System.out.println("period = " + period);
            period = 500;   // change the period time
            timer.cancel(); // cancel time
            startTimer();   // start the time again with a new period time
        }
    }, 0, period);
}
Bahramdun Adil
  • 5,907
  • 7
  • 35
  • 68
0

You can use the following class to change the execution period of a TimerTask at runtime.

As already explained, it can not really change the period but has to cancel and reschedule the task:

import java.util.Objects;
import java.util.Timer;
import java.util.TimerTask;
import java.util.function.Supplier;

/**
 * {@link TimerTask} with modifiable execution period.
 * 
 * @author Datz
 */
public class EditablePeriodTimerTask extends TimerTask {

    private Runnable task;
    private Supplier<Long> period;
    private Long oldP;

    /**
     * Constructor with task and supplier for period
     * 
     * @param task the task to execute in {@link TimerTask#run()}
     * @param period a provider for the period between task executions
     */
    public EditablePeriodTimerTask(Runnable task, Supplier<Long> period) {
        super();
        Objects.requireNonNull(task);
        Objects.requireNonNull(period);
        this.task = task;
        this.period = period;
    }

    private EditablePeriodTimerTask(Runnable task, Supplier<Long> period, Long oldP) {
        this(task, period);
        this.oldP = oldP;
    }

    public final void updateTimer() {
        Long p = period.get();
        Objects.requireNonNull(p);
        if (oldP == null || !oldP.equals(p)) {
            System.out.println(String.format("Period set to: %d s", p / 1000));
            cancel();
            new Timer().schedule(new EditablePeriodTimerTask(task, period, p), p, p);
            // new Timer().scheduleAtFixedRate(new EditablePeriodTimerTask(task, period), p, p);
        }
    }

    @Override
    public void run() {
        task.run();
        updateTimer();
    }

}

The Timer can bes started like this:

EditablePeriodTimerTask editableTimerTask =
    new EditablePeriodTimerTask(runnable, () -> getPeriod());
editableTimerTask.updateTimer();

Where runnable is your real task to be executed and getPeriod() provides the period between the task executions. Which of course can change depending on your requirements.

Datz
  • 3,156
  • 3
  • 22
  • 50
0
Timer timer = new Timer();  //should not create timer again 
private long periord = 1000; // periord is changed at runtime

public void runTaskPeriord() {
    
    TimerTask task = new TimerTask() {      
        @Override
        public void run() {
            log.debug("Task run" );
            if(periord <= 3000) {
                this.cancel();  // cancel this task to run new task
                periord += 1000; 
                runTaskPeriord();
            }
        }
    };
    
    timer.schedule(task, periord, periord);
    int countDeletedTasks = timer.purge(); // remove cancel task from timer

}
HungNM2
  • 3,101
  • 1
  • 30
  • 21