использование invokeLater - PullRequest
       18

использование invokeLater

0 голосов
/ 23 октября 2009

Я уверен, что все эти подходы будут работать, но я был бы признателен за мнения о том, какой из них является лучшим.

Рассмотрим в качестве аргумента (неудачный) сценарий, в котором пользовательский интерфейс изменяет код и смешивает достаточно интенсивный (в среднем 500 мс) логический код и неразделим . все изменяющиеся компоненты пользовательского интерфейса находятся на одной панели.

01 new Thread(){
02  public void run(){
03 
04  for (int i = 0; i < 100; i++){
05      // some processing
06      doSomething();
07      // update some ui components
08      panel.doSomeUi();
09  }
10 
11  panel.revalidate();
12  panel.repaint();
13 
14 }}.start();

Какой из следующих трех подходов вы бы выбрали и почему?

  1. обернуть весь код в invokeLater
  2. вызовите invokeLater внутри doSomeUi (), а затем снова для повторной проверки / перекраски
  3. использовать только invokeLater для повторной проверки / перекраски в конце

Для моего:

Опция 1 может повесить поток обработки событий (EPT), пока происходит вся обработка

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

вариант 3 будет наиболее эффективным, но может иметь некоторые проблемы с безопасностью потока

стремится услышать другие мнения.

Ответы [ 4 ]

3 голосов
/ 23 октября 2009

doSomeUi () некоторые должны быть заключены в invokeLater () и должны запускать любые необходимые перерисовки / перерисовки - поток Swing UI будет рисовать, пока вы продолжаете вычисления.

Затраты на создание множества недолговечных Runnable'ов будут незначительными на современной виртуальной машине и не должны быть проблемой.

Итак, вариант 2 (с предложенной модификацией) должен быть таким. При написании многопоточного кода медленное и правильное всегда лучше, чем быстрое и с ошибками.

1 голос
/ 02 июля 2012

revalidate and repaint безопасна для потоков. У них есть своя встроенная вещь invokeLater, вы можете вызывать revalidate и repaint из любого потока и в любое время. Это настолько умно сделано, что если вы вызываете revalidate тысячу раз, прежде чем он действительно что-либо проверяет, он объединит все эти тысячи вызовов в один вызов.

1 голос
/ 23 октября 2009

Сначала я бы запустил однопоточный. В качестве неотъемлемой части этого я хотел бы убедиться, что у меня есть хороший код (например, не расширяющий Thread и JPanel), с хорошим разделением «бизнес-логики» и пользовательского интерфейса, тестов и т. Д. это результат. Проверьте это в контроле версий. Тогда, возможно, посмотрите, есть ли небольшая горячая секция, которую я могу сделать параллельно.

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

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

Важно отметить, что действия, которые пользовательский интерфейс отправляет в «бизнес-модель», и обновления состояния в обратном направлении должны быть максимально разделены (т. Е. Работать с SwingWorker).

0 голосов
/ 23 октября 2009

Читали ли вы Урок Java: параллелизм в Swing и рассматривали возможность использования рабочих потоков. Также проверьте TumbleItem Пример

Урок прямо говорит:

Задачи в потоке отправки событий должен быстро закончить; если они этого не сделают, необработанные события резервного копирования и пользователя интерфейс перестает отвечать на запросы.

и

Когда необходимо выполнить программу Swing длительная задача, обычно она использует один из рабочих потоков

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