Резьбонарезное удержание / swingworkers - PullRequest
2 голосов
/ 05 сентября 2010

Я не уверен насчет удержания нити. В разгаре все компоненты графического интерфейса должны быть обновлены через EDT. SwingWorker предоставляется в Java6 для длительных операций, а в готовом методе компоненты графического интерфейса могут быть обновлены. Насколько я понимаю, компоненты GUI в методе done () обновляются в EDT. Поэтому не должно быть проблем с синхронизацией. Но здесь текст ссылки

это говорит:

Потому что класс ImageRetriever будет скачать изображение и поместить его на большая этикетка, обеспечивающая этикетку и URL изображения в конструкторе удобный. ImageRetriever нужен URL для получения изображения. Предоставить ярлык, чтобы ImageRetriever экземпляр может установить значок метки сам. Если вы используете внутренние классы, вы может даже не обеспечить это информация в конструкторе, потому что рабочий поток сможет получить доступ к информации напрямую. Тем не менее, предоставление информации в конструктор помогает вашему приложению быть более потокобезопасным, потому что это информация не будет передана ImageRetriever экземпляры

Я запутался в этом. Если методы SwingWorker обновляют компоненты графического интерфейса (в примере ссылки JLabel) в EDT, почему более потокобезопасно не делить их между экземплярами ImageRetriever (= SwingWorker)? Если у нас есть несколько SwingWorkers и в методе done () они обновляют один и тот же компонент, мы должны использовать примитивы синхронизации для обновления? Я что-то неправильно понимаю? Разве ограничение потока не означает, что только один поток будет выполнять все действия? Разве работники качели не ограничены нитями?

Спасибо

1 Ответ

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

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

Например:

SW in EDT - label.setText(...);
Thread1 - label = new JLabel();
SW in EDT - label.setIcon(...);

Если переменная метки является общей, вы получите несовместимое состояние (меткабез текста или значка).

Обновление Хранение метки в виде переменной, передаваемой через конструкторы, является способом избежать этой проблемы.Если вы хотите увидеть изменения, но не в середине выполнения метода, по пути следует использовать локальную переменную метода.Вы назначаете его в начале метода, чтобы убедиться, что он не будет изменен снаружи.

Если вы используете внутренние классы и атрибут родительского класса, это будет выглядеть так:

public void done() {
  JLabel l = label;
  l.setText(...);
  l.setIcon(...);
} 

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

...