Что делает SwingUtilities.invokeLater
? Просто задерживает выполнение блока кодов внутри своего метода run
? В чем разница между вызовом действия внутри функции invokeLater
или просто вызовом его в конце потока, который мы хотим выполнить? Может ли кто-нибудь помочь мне с тем, что на самом деле делает функция invokeLater
?
Что делает SwingUtilities.invokeLater?
Ответы (5)
Как уже говорилось в других ответах, он выполняет ваш Runnable
в потоке диспетчеризации событий AWT. Но зачем тебе это? Поскольку структуры данных Swing не являются потокобезопасными, поэтому, чтобы предоставить программистам легко достижимый способ предотвращения одновременного доступа к ним, разработчики Swing установили правило, согласно которому весь код, обращающийся к ним, должен выполняться в одном потоке. Это происходит автоматически для обработки событий и отображения кода обслуживания, но если вы инициировали длительное действие — конечно, в новом потоке — как вы можете сигнализировать о его ходе или завершении? Вы должны изменить элемент управления Swing, и вы должны сделать это из потока диспетчеризации событий. Отсюда invokeLater
.
Он запустит фрагмент кода в потоке AWT. Что позволяет изменять графический интерфейс из других потоков.
Из документов:
Вызывает асинхронное выполнение doRun.run() в потоке диспетчеризации событий AWT. Это произойдет после обработки всех ожидающих событий AWT. Этот метод следует использовать, когда потоку приложения необходимо обновить графический интерфейс.
Как уже отмечалось, InvokeLater позволяет вам безопасно вызывать методы в классах Swing, когда вы не работаете с EventQueue для начала. Однако вы можете упростить свой код и свою жизнь, получая доступ к другим полям и классам только из EventQueue. Они могут работать со свингом и друг с другом без всех проблем многопоточности. Если вы запустили другой поток, используйте InvokeLater, чтобы как можно быстрее вернуться к EventQueue и свести к минимуму количество полей, которые должны быть синхронизированы или иным образом защищены.
Если вам нужно максимально использовать несколько ядер, вам придется сократить использование EventQueue, и вам придется заплатить большую цену за сложность.
это был бы Комментарий, но выглядит длиннее, чем..., просто основные вещи
1/ создайте собственный EDT для правильного обновления графического интерфейса, например. если вы выполняете некоторый код, используя простой ванильный Thread, java.util.Timer, Executor .. больше здесь
2/ помогает установить Focus на JComponents, если есть несколько Listeners, потому что если есть DocumentListener, то вам трудно установить Focus
на желаемое JComponents
3/отложить блок выполнения кода и переместить его в конец EDT
Обратите внимание, что в конечном итоге вы получаете вызов метода doRun.run() каждый раз при вызове invokeLater(doRun). Таким образом, если вы вызовете его десять раз, прежде чем поток событий получит возможность выполнить свою обработку, вы, вероятно, получите десять последовательных вызовов doRun.run().