Зачем использовать SwingUtilities.invokeLater в основном методе?
После многих лет программирования на Java я всегда создавал свои main()
методы как это:
public static void main(String[] args)
{
runProgram();
}
Но недавно я изучил некоторые коды из Интернета и видел это иногда вместо обычного main()
используйте выше:
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
runProgram();
}
});
}
Я просто хочу знать:
- Зачем использовать это вместо обычного
main()
путь? Я не вижу никакой разницы, когда я попробую. - В чем разница между этими двумя способами?
Спасибо, что прочитали меня и ваши ответы.
4 ответа
Документы объясняют почему. Из начальных тем
Почему первоначальный поток просто не создает сам графический интерфейс? Потому что почти весь код, который создает компоненты Swing или взаимодействует с ними, должен выполняться в потоке диспетчеризации событий.
Некоторые методы компонента Swing помечены как "потокобезопасные" в спецификации API; их можно безопасно вызывать из любого потока. Все остальные методы компонента Swing должны вызываться из потока диспетчеризации событий. Программы, которые игнорируют это правило, могут работать правильно большую часть времени, но подвержены непредсказуемым ошибкам, которые трудно воспроизвести.
Поскольку поток "main", запущенный VM, не является потоком отправки событий.
Некоторые компоненты Swing из API не являются поточно-ориентированными, что означает, что они могут вызывать некоторые проблемы, такие как взаимоблокировка. Поэтому лучше создавать и обновлять такие компоненты Swing с помощью потока диспетчера событий, предоставленного Swing, но не из основного потока или любого другого нить создана из основного.
Хотя приведенные выше ответы верны, я считаю, что им не хватает правильного объяснения.
Да, все, что взаимодействует со Swing (создание пользовательского интерфейса, его обновление, добавление новых компонентов или макетов и т. Д.), Всегда должно выполняться в потоке диспетчеризации событий AWT (см. Этот пост для получения дополнительной информации по теме).
помещает ваш код в очередь FIFO потока отправки событий (EDT), поэтому он будет выполняться из EDT всякий раз, когда он завершит другие задачи, которые он выполнял.
При этом EDT следует использовать исключительно для выполнения задач, связанных с Swing, которые быстро выполняются (если вы блокируете EDT, вы блокируете весь пользовательский интерфейс).
Нет смысла использовать
SwingUtilities.invokeLater()
в основном методе, если вы не используете Swing / AWT (например, приложение JavaFX или приложение терминала).
Если вы хотите выполнить некоторые задачи, которые не имеют никакого отношения к Swing, но они необходимы для запуска Swing (например, запуск модели и контроллера в приложении, подобном MVC), вы можете сделать это из EDT или из основного потока. (см. этот пост для обсуждения этой темы).