Таймер 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. Однако, когда я это делаю, я получаю исключение из нелегального штата. Вы можете увидеть System.out.println(таймер); там, потому что я проверяю, и, конечно же, у них два разных таймера... так почему я получаю исключение IllegalStateException, когда я пытаюсь запустить расписание для нового экземпляра Timer!?!?!?!
[email protected]
[email protected]
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)
Ответы
Ответ 1
Вы не можете повторно использовать TimerTask, как вы здесь делаете.
Соответствующая позиция Timer:
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 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, а не повторно использовать его.
Ответ 2
Мне кажется странным иметь TimerTask со своим таймером внутри него. Плохой дизайн. Я бы полностью отделил их, и реализация TimerTask будет передана таймеру, и поместит всю эту логику, чтобы переиграть период внутри другого класса, который обеспечивает интерфейс для этого. Пусть этот класс создает экземпляр Timer и TimerTask и отправляет их для выполнения своей работы.
Ответ 3
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.....
}
}