How can I change my TimerTask's execution period at runtime?I
How can I change period of Timer at runtime?
Timer timer = new Timer();
timer.scheduleAtFixedRate(new Timer开发者_高级运维Task() {
public void run() {
// read new period
period = getPeriod();
doSomething();
}
}, 0, period);
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.
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);
}
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.
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
}
精彩评论