Синхронизация компонентов Swing - PullRequest
6 голосов
/ 22 июня 2011

Я читаю Потоки Java 3-е изд.Оукс и Вонг (O'Reilly 2004).Они несут пример игры в Swing на протяжении всей книги.Классы, которые они определяют, в основном являются пользовательскими подклассами javax.swing.JComponent.

. Что мне кажется совершенно неправильным, так это то, что они делают эти JComponent потокобезопасными с различными методами синхронизации.У меня сложилось впечатление, что компоненты Swing не должны быть потокобезопасными, а скорее, что к ним всегда нужно обращаться из потока диспетчеризации событий Swing.(Забавно, один из немногих случаев, когда они модифицируют компонент через Swing EDT, это для setText, который является одним из очень немногих методов Swing, которые не нужно вызывать из EDT.)

Я хотел бы знать от некоторых из вас, кто имеет большой опыт написания / чтения кода Swing: часто ли программисты синхронизируют компоненты Swing вместо того, чтобы всегда модифицировать их через EDT?Это терпимо?

РЕДАКТИРОВАТЬ:
Я заметил, что это почти такой же вопрос, как этот поток .Однако это не говорит о том, что программисты на самом деле делают в дикой природе.Я озадачен тем, что книга О'Рейли так грубо нарушает модель потоков Swing.

РЕДАКТИРОВАТЬ:
Я обнаружил, что они кратко объясняют где-то в середине книгимодель Swing Threading.Тем не менее, я хотел бы получить ответ на мой вопрос.У меня такое чувство, что большинство, кто читает эту книгу, в конечном итоге нарушат модель потоков Swing, поскольку большинство их примеров делают это.

РЕДАКТИРОВАТЬ:
Если вы хотите посмотреть на код,Вы можете Скачать примеры кода в виде zip-файла.См., Например, ch03 / example1 / AnimatedCharacterDisplayCanvas.

РЕДАКТИРОВАТЬ:
Я только что узнал, что setText не будет поточно-ориентированным в Java7 (выпуск в июле 2011 года).

Ответы [ 3 ]

2 голосов
/ 22 июня 2011

У вас никогда не должно быть синхронизированных блоков в компонентах Swing, это может вызвать странные проблемы при попытке рендеринга.

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

Долгосрочные процессы должны быть перемещены в фоновый поток или SwingWorker.Когда поток, отличный от EDT, должен создавать компоненты или обновлять компонент, он должен быть упакован с использованием SwingUtilities.invokeLater ()

2 голосов
/ 23 июня 2011

Тривиально, пока синхронизированные методы не выполняются на EventQueue, они не будут блокировать поток отправки событий.И наоборот, метод, выполняющийся в другом потоке, должен всегда использовать EventQueue для отправки кода через invokeLater(), invokeAndWait() или связанный механизм, такой как javax.swing.Timer или javax.swing.SwingWorker.На практике это надежно.Примеры могут быть правильными, но их следует рассматривать с этой точки зрения.

API EventQueue гласит: «Единственными требованиями являются события ...отправляются ... в том же порядке, что и в очереди ".На мой взгляд, это равносильно отношению «произойдет до» java.util.concurrent и JLS.Более подробное обсуждение можно найти здесь .

0 голосов
/ 22 июня 2011

"Компоненты Swing не являются поточно-ориентированными по своей природе, и, как правило, после того, как компоненты Swing стали видимыми на экране, вы можете безопасно изменять только свои данные из потока событий. Если вы изменяете данные компонента Swing из любого потока кроме потока диспетчеризации событий, вы должны принять меры предосторожности для обеспечения целостности данных. Исключением из этого правила является метод setText для JTextComponent или любого из его подклассов, или любой метод компонента Swing, в документации которого явно указано, что он безопасен для потоков ». Моника Павлан http://java.sun.com/developer/technicalArticles/Threads/swing/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...