Разрешено ли загружать классы Swing в не-EDT-потоке? - PullRequest
8 голосов
/ 07 июня 2010

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

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

Разъяснение по вопросу Неми: это практический вопрос. Значительная часть времени запуска нашего приложения тратится на загрузку классов и загрузку шрифтов / изображений в EDT. Большая часть этого может быть приписана Swing и связанным библиотекам.

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

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

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

Ответы [ 3 ]

2 голосов
/ 09 июня 2010

Это безопасно. См .: 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 («Проверка того, что доступ к компонентам GUI выполняется в EDT») - это пользовательский RepaintManager, который не срабатывает при нарушении политики доступа к EDT.

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

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

2 голосов
/ 09 июня 2010

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

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

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

0 голосов
/ 08 июня 2010

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

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

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

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

...