Подтвердить что ты не робот

Таймер 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)
4b9b3361

Ответ 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.....
    }
    }