Java计时器

我正在尝试使用计时器来安排应用程序中的重复事件。 但是,我希望能够实时调整事件触发的时间段(根据用户输入)。

例如:

public class HelperTimer extends TimerTask { private Timer timer; //Default of 15 second between updates private int secondsToDelay = 15; public void setPeriod(int seconds) { this.secondsToDelay = seconds; long delay = 1000; // 1 second long period = 1000*secondsToDelay; // seconds if (timer != null) { timer.cancel(); } System.out.println(timer); timer = new Timer(); System.out.println(timer); timer.schedule(this, delay, period); } public int getPeriod() { return this.secondsToDelay; } } 

然后我启动这个类的新实例并调用它的set period函数。 但是,当我这样做时,我得到一个非法状态exception。 你可以看到System.out.println(计时器); 因为我正在检查,并且确实如此,它们是两个不同的计时器……所以当我尝试在全新的Timer实例上运行计划调用时,为什么会出现IllegalStateException!?!?!?!

 java.util.Timer@c55e36 java.util.Timer@9664a1 Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Task already scheduled or cancelled at java.util.Timer.sched(Unknown Source) at java.util.Timer.schedule(Unknown Source) at HelperTimer.setPeriod(HelperTimer.java:38) 

你不能像在这里那样重复使用TimerTask。

计时器的相关部分:

 private void sched(TimerTask task, long time, long period) { if (time < 0) throw new IllegalArgumentException("Illegal execution time."); synchronized(queue) { if (!thread.newTasksMayBeScheduled) throw new IllegalStateException("Timer already cancelled."); synchronized(task.lock) { //Right here's your problem. // state is package-private, declared in TimerTask if (task.state != TimerTask.VIRGIN) throw new IllegalStateException( "Task already scheduled or cancelled"); task.nextExecutionTime = time; task.period = period; task.state = TimerTask.SCHEDULED; } queue.add(task); if (queue.getMin() == task) queue.notify(); } } 

您需要重构代码,以便创建新的TimerTask,而不是重新使用它。

我觉得有一个TimerTask里面有自己的Timer似乎很奇怪。 糟糕的设计。 我完全将这两者分开,并将TimerTask实现交给Timer,并将所有关于摆动的逻辑放在另一个提供接口的类中。 让该类实例化Timer和TimerTask并将它们发送出去完成它们的工作。

  import java.util.*; class TimeSetting { public static void main(String[] args) { Timer t = new Timer(); TimerTask time = new TimerTask() { public void run() { System.out.println("Executed......"); } }; t.scheduleAtFixedRate(time, 4000, 3000); // The task will be started after 4 secs and // for every 3 seconds the task will be continuously executed..... } }