Таймер Java с потоком

#java #multithreading #timer

#java #многопоточность #таймер

Вопрос:

Я разрабатываю простое приложение и использую таймер, но если я запускаю таймер несколько раз, таймер удаляет это исключение: Исключение в потоке «AWT-EventQueue-0» java.lang.Исключение IllegalStateException: таймер уже отменен. Вот мой код:

 public class Main {

...
private static void createAndShowUI() {
    ...
    //a listener of a radio button
    ActionListener on_action = new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            Timer.timer.schedule(Timer.task,0,2000);   //I call the timer here 
        }
    };
    ...
}
public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {
          public void run() {
            createAndShowUI();
          }
        });
 }


}
//and the class of timer:
public class Timer {


public static java.util.Timer timer = new java.util.Timer();
public static java.util.TimerTask task = new java.util.TimerTask() {


    public void run() {
        //some tasks
    }
};
}
  

Мой вопрос в том, где я использую поток? Спасибо!

Ответ №1:

Проблема не в использовании потока очереди событий, а в том, что вы повторно используете отмененный таймер.

Я предполагаю, что вы используете таймер для выполнения некоторой анимации или чего-то еще в ответ на нажатие кнопки (поскольку вы планируете выполнение операций с фиксированной скоростью). Я предполагаю также, что в коде, который вы нам не показываете, таймер отменяется отдельным событием. Если вы когда-нибудь вызовете Timer.cancel(), вы можете показать нам этот код?

Из исключения происходит то, что вы пытаетесь использовать тот же таймер, который вы уже отменили. После отмены таймера его нельзя использовать снова.

Два предложения — каждый раз используйте другой таймер. Кроме того, если вы делаете что-то для целей пользовательского интерфейса, вы можете рассмотреть возможность использования таймера Swing вместо этого.

Что касается потока, все события GUI происходят в потоке AWT, но я повторяю, это почти наверняка не проблема. Прочитайте это для получения более подробной информации.

Ответ №2:

Таймер переходит в состояние отменено, если был вызван cancel() метод или если задача таймера неожиданно завершилась:

Если поток выполнения задачи таймера неожиданно завершается, например, из-за вызова его метода stop, любая дальнейшая попытка запланировать задачу на таймере приведет к исключению IllegalStateException, как если бы был вызван метод cancel таймера.

Таким образом, в вашем случае это может быть проблема не в том, куда вы вкладываете / вызываете / используете свое время, а скорее в том, что вы на самом деле делаете со своим таймером.

Комментарии:

1. У меня есть приложение для моделирования движения, и я использую автоматический семафор для моделирования внутри таймера, и есть панель, где вы можете изменять количество транспортных средств и скорость транспортных средств. Но если я изменю, например, количество транспортных средств, это не окажет никакого эффекта на симуляцию

2. @JoshWistake — Один таймер для полной симуляции или один экземпляр таймера для одной машины? И если это для одной симуляции (мое предположение), то почему вам нужно вызывать это несколько раз?

Ответ №3:

Здесь у вас есть ваш поток:

Каждому объекту Timer соответствует отдельный фоновый поток, который используется для последовательного выполнения всех задач таймера

поэтому, если вы попытаетесь получить доступ к вашему GUI из задачи Timer, вы должны поместить ее в поток EventQueue.

И посмотрите здесь

Если поток выполнения задачи таймера неожиданно завершается, например, из-за вызова его метода stop, любая дальнейшая попытка запланировать задачу на таймере приведет к исключению IllegalStateException, как если бы был вызван метод cancel таймера.

Позволяете ли вы таймеру планировать какие-либо дополнительные задачи после его отмены?