Является ли обновление из EDT в разгаре абсолютным правилом или есть исключения? - PullRequest
1 голос
/ 04 сентября 2010

В Swing графический интерфейс должен обновляться только EDT, поскольку компоненты графического интерфейса не являются поточно-ориентированными.

У меня вопрос: если у меня есть один поток, отличный от EDT, который предназначен для обновления определенного компонента, и этот компонент не доступен ни одному другому потоку в моей программе, только этот выделенный поток, это нормально? ? В моем случае у меня есть JTable, и поток получает информацию из сети и обновляет таблицу (без использования EventQueue.invokeLater). Все остальные компоненты обновляются из EDT. До сих пор я не видел проблемы, и мне было интересно, появится ли ошибка в конечном итоге.

UPDATE Моей целью было обновить таблицу в режиме реального времени. Данные постоянно поступают из сети, и для этого я выделил 1 поток только для таблицы, чтобы постоянно обновлять ее по мере их поступления. Если я использую SwingUtilities.invokeLater, это означает, что таблица будет обновлена, когда будет доступно EDT. Разве свинг не должен использоваться для обновления в реальном времени?

Ответы [ 5 ]

6 голосов
/ 04 сентября 2010

Вместо того, чтобы пытаться рассуждать о том, будет ли это работать или нет, я бы просто придерживался хорошо известного «правила», заключающегося в том, что вы должны взаимодействовать только с компонентами GUI, используя поток диспетчеризации событий.Когда вы получаете данные из сети, просто обновите таблицу, используя SwingUtilities.invokeLater (или invokeAndWait).

Вы можете не сразу увидеть проблемы, но вполне возможно, что вы это сделаете в будущем.

4 голосов
/ 04 сентября 2010

Есть несколько методов, задокументированных как поточно-ориентированные.Я верю немного меньше в JDK7, потому что оказывается, что некоторые из них нереализуемы как поточно-ориентированные.По большей части Swing является враждебным к потоку - его следует использовать из потока AWT EDT.Это в значительной степени потому, что он использует EventQueue.invokeLater внутри "случайно".Также есть скрытое общее состояние (вы можете изменить PL & F без необходимости указывать, например, каждый компонент).Некоторые классы вы можете рассматривать как независимые от потоков, но они не документированы как таковые.

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

2 голосов
/ 04 сентября 2010

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

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

Если вы работаете с обновлением живых таблиц, я настоятельно рекомендую вам взглянуть на GlazedLists - у них есть очень, очень хорошая реализация SwingThreadProxyList, которая эффективно заботитсяразмещение обновлений в EDT.Вы должны согласиться выпить koolaid GlazedLists, чтобы пойти этим путем, но это очень вкусный koolaid (я люблю GL).

1 голос
/ 04 сентября 2010

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

1 голос
/ 04 сентября 2010

Разве Swing не должен использоваться для требований обновления в реальном времени?

Нет.Вы можете обновить модель данных с достаточной скоростью, но графический интерфейс обычно подчинен.Вы можете воспользоваться любой задержкой сети в вашей среде.В качестве альтернативы вам может потребоваться рассмотреть что-то вроде Oracle * Sun Java Real-Time System .

Вы можете улучшить "жизнеспособность" EDT, оставляя обновления краткимииспользуя минимальную, правильную синхронизацию.Несколько альтернатив обсуждаются здесь .

...