Java 如何更改我的TimerTask';运行时的执行周期是多少

Java 如何更改我的TimerTask';运行时的执行周期是多少,java,timer,timertask,Java,Timer,Timertask,如何在运行时更改计时器的周期 Timer timer = new Timer(); timer.scheduleAtFixedRate(new TimerTask() { public void run() { // read new period period = getPeriod(); doSomething(); } }, 0, period);

如何在运行时更改计时器的周期

    Timer timer = new Timer();

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

             // read new period
             period = getPeriod();

             doSomething();

        }
    }, 0, period);

您不能直接执行此操作,但可以取消
计时器上的任务
,并按所需时间重新安排任务


没有
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);
}
EditablePeriodTimerTask editableTimerTask =
    new EditablePeriodTimerTask(runnable, () -> getPeriod());
editableTimerTask.updateTimer();

您可以使用以下类在运行时更改
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();
    }

}

其中,
runnable
是要执行的实际任务,
getPeriod()
提供任务执行之间的时间间隔。当然,这会根据您的要求而变化。

不幸的是,我认为您必须根据新的时段安排新的计时器。无论如何,您应该使用一个
ScheduledExecutorService
@佩什凯拉,OP已经知道了这个方法,但是他问是否有可能在运行时改变周期,这是不可能的。你不能重新安排现有的TimerTask。一旦取消,它将不再运行。您需要创建一个新的TimerTask实例。