Что делает SwingUtilities.invokeLater?
Описание проблемы
У меня возникли вопросы по поводу работы метода <code>SwingUtilities.invokeLater</code>
в Java. Что именно делает этот метод? Он просто задерживает выполнение блока кода внутри своего метода <code>run</code>
? В чем разница между вызовом действия внутри функции <code>invokeLater</code>
и простым вызовом этого действия в конце потока, который мы хотим выполнить?
Было бы очень полезно, если кто-то смог бы объяснить, как именно работает функция <code>invokeLater</code>
, так как мне не совсем понятно её назначение и использование. Спасибо!
3 ответ(ов)
Как упоминали в других ответах, этот метод выполняет ваш Runnable
в потоке обработки событий AWT. Но зачем это нужно? Дело в том, что структуры данных Swing не являются потокобезопасными, и чтобы дать программистам простой способ предотвратить одновременный доступ к ним, разработчики Swing установили правило, что весь код, взаимодействующий с этими структурами, должен выполняться в одном и том же потоке. Это происходит автоматически для кода, отвечающего за обработку событий и обновление отображения. Однако если вы запускаете длительное действие в новом потоке, как вы сможете сообщить о его прогрессе или завершении? Вам нужно изменить элемент управления Swing, и делать это необходимо из потока обработки событий. Поэтому и был введен метод invokeLater
.
Как уже было отмечено, метод invokeLater
позволяет безопасно вызывать методы в классах Swing, когда вы не находитесь в потоке события. Однако вы можете упростить ваш код и жизнь, обращаясь к другим полям и классам только из потока событий. Это позволяет работать как с Swing, так и между собой, избегая всех проблем, связанных с многопоточностью. Если вы запустили другой поток, используйте invokeLater
, чтобы как можно быстрее вернуться в поток событий и минимизировать количество полей, которые необходимо синхронизировать или охранять иным образом.
Если вы хотите максимально использовать возможности многоядерности, вам придётся снизить использование потока событий, что приведёт к значительному увеличению сложности.
Обратите внимание, что метод doRun.run() будет вызван каждый раз, когда вы вызываете invokeLater(doRun). То есть, если вы вызовете его десять раз до того, как поток обработки событий получит возможность выполнить свои задачи, скорее всего, вы получите десять последовательных вызовов doRun.run().
SwingUtilities.invokeLater: Вызов кода в потоке событий Swing
Что значит 'synchronized'?
Разница между интерфейсами Runnable и Callable в Java
Как распределяются потоки для обработки запросов Servlet?
Следует ли использовать отдельные экземпляры ScriptEngine и CompiledScript для каждого потока?