如何在运行时更改Timer的周期?
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
// read new period
period = getPeriod();
doSomething();
}
}, 0, period);
您不能直接执行此操作,但您可以取消Timer
上的任务,并按所需时间重新安排。
没有getPeriod
方法。
你可以这样做:
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);
}
您可以使用以下类在运行时更改TimerTask
的执行周期。
如前所述,它不能真正改变周期,但必须取消并重新安排任务:
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();
}
}
计时器可以这样启动:
EditablePeriodTimerTask editableTimerTask =
new EditablePeriodTimerTask(runnable, () -> getPeriod());
editableTimerTask.updateTimer();
其中runnable
是要执行的实际任务,getPeriod()
提供任务执行之间的时间段。当然,这可能会根据您的要求而改变。
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
}