Позволяется загрузить классы Swing в потоке не-EDT?

После введения Модели памяти Java инструкции Swing были изменены, чтобы указать, что любые компоненты Swing нужно инстанцировать на EDT для предотвращения неопубликованного состояния экземпляра.

Что я не мог найти, где-нибудь, получает ли classloading также мандат быть на EDT, или мы можем предварительно загрузить ключевые классы Swing в фоновом потоке? Есть ли какое-либо официальное заявление от Sun/Oracle на этом? Есть ли какие-либо классы, которые, как известно, содержат неориентированное на многопотоковое исполнение статическое состояние, следовательно должен быть загружен на EDT?

Разъяснение для рассматривания вопроса Nemi: это - практическая проблема. Значительная часть времени запуска нашего приложения, потрачен на classloading и font/image-loading на EDT. Большая часть из этого может быть приписана Swing и связанным библиотекам.

Вот som фон: Как много других приложений Swing, на запуске мы предварительно создаем много форм для создания UI более быстро реагирующим. После профилирования мы нашли, что фактическое время для конструкции формы относительно быстро - что является медленным, загружается всех классов, и шрифты (чтение с диска является медленным в корпоративной установке с вирусным сканером при запуске, сканером наблюдения, контролирует средство отслеживания, и бог знает то, что еще лавировало на драйвере жесткого диска).

Мы пытались создать те же формы в фоновом потоке (нарушающий правила Swing) и затем выбросить их. После того как мы сделаны, мы создаем те же формы на EDT, который намного быстрее, поскольку все классы загружаются, и любые другие файлы находятся в дисковом кэше. Это работает на нас, и мы будем, вероятно, продолжать делать его, если чего-то действительно плохо не произойдет.

То, что я спрашиваю, - является ли это безопасной практикой, хорошей практикой или взломом?

8
задан ddimitrov 7 June 2010 в 23:09
поделиться

3 ответа

Доказательства вроде бы говорят о том, что это безопасно - но опять же, как говорит ddimitrov в комментариях - шансы в пользу того, что не будут найдены тонкие ошибки в потоках из-за неопубликованных изменений, потому что типичные машины имеют всего несколько ядер, а кэши L2/L3 общие. (Кэши L1 - на каждое ядро, но обычно очень маленькие.)

Если вы хотите гарантировать, что не возникнет проблем из-за фоновой загрузки классов, то, вероятно, безопаснее всего придерживаться загрузки классов на ETD. Для поддержания живого пользовательского интерфейса создайте пользовательский загрузчик классов, который также передает события между загрузкой каждого класса. (Зависимости загружаются реентерабельно, поэтому задержка будет только на время загрузки одного класса). Предположим, что этот загрузчик классов упакован с вашим приложением, тогда он может просто отложить загрузку всех классов на свой загрузчик классов.

В качестве альтернативы можно использовать вторичные очереди событий, которые выполняются в отдельных потоках (например, модальные диалоги и библиотека spin). Это означает, что Swing может работать в любом потоке, пока он работает только в одном, и означает, что он должен быть совместим с обновлениями (или что нам всем просто очень повезло до сих пор!) Исходя из этого, вы можете загрузить свои классы в первичный EDT, и запустить вторичный EDT для обработки событий пользовательского интерфейса, сохраняя пользовательский интерфейс отзывчивым - так же, как функционирует модальный диалог. Утилита Spin будет накачивать события EDT за вас, или вы можете породить новый EDT вручную.

2
ответ дан 6 December 2019 в 00:05
поделиться

Хотя вы технически правы - я никогда не слышал о проблеме с рендерингом форм в другом потоке, если вы ничего не делаете с ними после их реализации, кроме как с EDT (согласно первоначальным рекомендациям Sun).

Раньше это были рекомендации Sun, но Sun изменила их, чтобы они были такими, как вы указали - так что я уверен, что кто-то обнаружил или создал потенциальный конфликт, но я также уверен, что это будет чертовски сложно, поскольку приложения все еще работают и почти никто не соблюдает эти правила.

Что касается вашего вопроса, я уверен, что вы можете загружать классы, если вы не создаете экземпляры каких-либо объектов и при этом соблюдаете даже самые строгие правила.

EDT используется только для предотвращения конфликтов потоков, поскольку Swing является однопоточным (по замыслу). Если вы только загружаете классы и не создаете их экземпляров, вы не открываете себя для каких-либо проблем с потоками.

0
ответ дан 6 December 2019 в 00:05
поделиться

Это безопасно. См .: http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html (правило одного потока)

Если вы боитесь или хотите получить обратную связь / отладку , взгляните на этот инструмент FEST / Swing: http://fest.easytesting.org/swing/wiki/pmwiki.php?n=FEST-Swing.EDT ("Проверка доступа к компонентам графического интерфейса выполняется в EDT ") - это пользовательский RepaintManager , который не работает, когда вы нарушаете политику доступа EDT.

Вы также можете найти это полезным: http://weblogs.java.net/blog/alexfromsun/archive/2006/02/debugging_swing.html

В них явно не упоминается загрузка классов, но они действительно объясняют, что такое политика доступа EDT.

2
ответ дан 6 December 2019 в 00:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: