Последовательность выполнения операций
Пытаюсь разобраться с использованием классов swing. Возник такой вопрос:
предположим в начале программы я создаю объект swing Timer и запускаю его
Timer myTimer = new Timer(1000,this);
myTimer.start();
Далее программа продолжается, выполняются какие-нибудь расчёты, вычисления и т.д. Но проходит 1000 мсек и myTimer вызывает метод actionPerformed(). Хочу понять в какой последовательности будут выполнятся операции. Может быть основная программа остановится и будет ожидать пока не закончится выполнение метода actionPerformed()? А может быть какой другой вариант? Кто в курсе подскажите, как на самом деле будут выполняться операции?
Ответы (1 шт):
Для того чтобы объяснить как работает таймер рассмотрим, как в общем работает swing, а точнее AWT, на котором swing основывается.
AWT запускает специальный фоновый поток (thread), задачей которого является обработка событий в приложении. Условно, этот поток работает так:
while (true) {
while (eventQueue.isEmpty()) {
sleep(1);
}
processEvent(eventQueue.getNext());
}
Т.е. этот поток в цикле достает события из очереди и обрабатывает их доставляя соответствующим обработчикам (классам реализующим ActionListener). В очередь же события добавляются после действия пользователя (нажатие на кнопку или ввод в текстовое поле), программно - используя механизмы типа invokeLater или по событию от таймера.
Важный момент, что этот поток выполнения, не тот же, в котором выполняется метод main, а специально предназначенный для обработки событий. Т.е. главный поток приложения может делать какие-то действия , а при этом поток обработки событий будет работать параллельно. Конечно, они могут взаимодействовать, и в этом случае нужна синхронизация, как и при любом использовании многопоточности.
Теперь собственно о таймере.
Timer из swing работает совместно з общим механизмом обработки событий. То есть когда приходит время срабатывать таймеру, то событие срабатывания таймера добавляется в очередь событий. События из очереди обрабатываются как и другие события типа нажатия на кнопку и т.п., т.е. в основном потоке обработки событий.
Из этого следует, что actionPerformed не вызовется моментально, если в этот момент обрабатывается другое событие. Это произойдет после того, как все события случившиеся до срабатывания таймера, будут обработаны. Если при этом основной поток выполняет что-то, обработчик таймера будет выполнен параллельно с действиями в главном потоке.