Что делает SwingUtilities.invokeLater?

Что делает SwingUtilities.invokeLater? Просто задерживает выполнение блока кодов внутри своего метода run? В чем разница между вызовом действия внутри функции invokeLater или просто вызовом его в конце потока, который мы хотим выполнить? Может ли кто-нибудь помочь мне с тем, что на самом деле делает функция invokeLater?


person Community    schedule 04.07.2011    source источник
comment
См. также stackoverflow.com/questions/5780936/ для фона (связанный фон, но не дубликат).   -  person Donal Fellows    schedule 04.07.2011


Ответы (5)


Как уже говорилось в других ответах, он выполняет ваш Runnable в потоке диспетчеризации событий AWT. Но зачем тебе это? Поскольку структуры данных Swing не являются потокобезопасными, поэтому, чтобы предоставить программистам легко достижимый способ предотвращения одновременного доступа к ним, разработчики Swing установили правило, согласно которому весь код, обращающийся к ним, должен выполняться в одном потоке. Это происходит автоматически для обработки событий и отображения кода обслуживания, но если вы инициировали длительное действие — конечно, в новом потоке — как вы можете сигнализировать о его ходе или завершении? Вы должны изменить элемент управления Swing, и вы должны сделать это из потока диспетчеризации событий. Отсюда invokeLater.

person Maurice Naftalin    schedule 04.07.2011
comment
ох! так вот как вы можете выполнять асинхронную однопоточность в java! Странно, что он должен быть связан с набором инструментов для работы с окнами, хотя это кажется немного неуместным. - person Dmitry; 20.07.2016
comment
@Dmitry Это забавный способ посмотреть на это. Java не обеспечивает поддержку однопоточности на уровне языка (есть ли язык?). Таким образом, фреймворк, который требует этого, должен предоставлять функции для его поддержки и устанавливать правила для корректного использования клиентским программистом. Это не способ сделать это на Java, а способ сделать это на Java. - person Maurice Naftalin; 21.07.2016

Он запустит фрагмент кода в потоке AWT. Что позволяет изменять графический интерфейс из других потоков.

Из документов:

Вызывает асинхронное выполнение doRun.run() в потоке диспетчеризации событий AWT. Это произойдет после обработки всех ожидающих событий AWT. Этот метод следует использовать, когда потоку приложения необходимо обновить графический интерфейс.

person MByD    schedule 04.07.2011

Как уже отмечалось, InvokeLater позволяет вам безопасно вызывать методы в классах Swing, когда вы не работаете с EventQueue для начала. Однако вы можете упростить свой код и свою жизнь, получая доступ к другим полям и классам только из EventQueue. Они могут работать со свингом и друг с другом без всех проблем многопоточности. Если вы запустили другой поток, используйте InvokeLater, чтобы как можно быстрее вернуться к EventQueue и свести к минимуму количество полей, которые должны быть синхронизированы или иным образом защищены.

Если вам нужно максимально использовать несколько ядер, вам придется сократить использование EventQueue, и вам придется заплатить большую цену за сложность.

person RalphChapin    schedule 05.07.2011

это был бы Комментарий, но выглядит длиннее, чем..., просто основные вещи

1/ создайте собственный EDT для правильного обновления графического интерфейса, например. если вы выполняете некоторый код, используя простой ванильный Thread, java.util.Timer, Executor .. больше здесь

2/ помогает установить Focus на JComponents, если есть несколько Listeners, потому что если есть DocumentListener, то вам трудно установить Focus на желаемое JComponents

3/отложить блок выполнения кода и переместить его в конец EDT

person mKorbel    schedule 04.07.2011

Обратите внимание, что в конечном итоге вы получаете вызов метода doRun.run() каждый раз при вызове invokeLater(doRun). Таким образом, если вы вызовете его десять раз, прежде чем поток событий получит возможность выполнить свою обработку, вы, вероятно, получите десять последовательных вызовов doRun.run().

person gerardw    schedule 03.12.2012