О EDT (Java)

Я прочитал несколько статей в Интернете о том, когда что-то должно работать в EDT, а когда нет. Но я все еще не уверен, что понимаю, поэтому я хотел бы задать несколько вопросов по этому поводу:

  1. Какие фрагменты кода будут выполняться по умолчанию внутри EDT?

  2. Какие фрагменты кода будут выполняться по умолчанию за пределами EDT?

  3. Когда я должен использовать InvokeLater(), чтобы что-то, что по умолчанию будет работать вне EDT, будет работать внутри него?

  4. Когда я должен предотвратить выполнение фрагмента кода (по умолчанию) внутри EDT, создав новый поток и поместив в него этот код?

Спасибо


person user3150201    schedule 03.01.2014    source источник


Ответы (2)


  1. Весь код, выполняемый прослушивателем событий.
  2. Код в вашем основном методе, код, выполняемый внутри потока, который вы явно запустили или который был запущен с использованием Timer или SwingWorker.
  3. При создании графического интерфейса Swing в вашем основном методе. Или когда вы хотите взаимодействовать с компонентом Swing (или его моделью) из фонового потока.
  4. Когда этот фрагмент кода блокируется (например, длинный ввод-вывод) или его выполнение занимает более нескольких миллисекунд. Весь код, выполняемый внутри EDT, не позволяет этому потоку выполнять свою основную работу: перекрашивать графический интерфейс и реагировать на события.
person JB Nizet    schedule 03.01.2014
comment
Спасибо за ответ. Об ответе 1: Вы имеете в виду, что ТОЛЬКО тип кода, который будет запускаться по умолчанию в EDT, - это код в методах actionPerformed()? Ничего больше? - person user3150201; 03.01.2014
comment
Не только actionPerformed(). Все методы обработки событий других типов прослушивателей (ItemListener, MouseListener, SelectionListener и т. д.). И, конечно же, он транзитивный: если actionPerformed() вызывает foo(), которая вызывает bar(), которая вызывает baz(), все эти методы выполняются в EDT. В типичном приложении с графическим интерфейсом почти все выполняется в ответ на событие. - person JB Nizet; 03.01.2014
comment
Хорошо. Вызов repaint() в классе, расширяющем JPanel, выполняется в EDT? - person user3150201; 03.01.2014
comment
Невозможно сказать. Распечатайте трассировку стека, и вы узнаете, откуда исходит этот вызов repaint(). Или используйте отладчик, чтобы узнать. Один метод может быть вызван из многих потоков. repaint() можно безопасно вызывать из любого потока. - person JB Nizet; 03.01.2014
comment
в основном 1) имеет какое-либо отношение к Swing API, но, возможно, это слишком обобщенно. Действия paint() действительно также происходят там, например, но не в тот момент, когда вы вызывали бы repaint(). SwingWorker и SwingUtilities.invokeLater() — это еще один способ заставить что-то работать в EDT. - person Gimby; 03.01.2014
comment
Допустим, у меня есть игра с игровым циклом, который запускается каждые 10 миллисекунд. В конце этого игрового цикла есть repaint(), что означает, что repaint() вызывается каждые 10 мс. Должен ли я поместить repaint() в другой поток, чтобы он не запускался в EDT? - person user3150201; 03.01.2014
comment
Ваш игровой цикл уже является фоновым потоком, отличным от EDT. Вы можете безопасно вызывать repaint() из этого фонового потока. Это просто попросит EDT перерисовать графический интерфейс через некоторое время. В результате через некоторое время метод paintComponent() панели будет вызываться Swing внутри EDT. - person JB Nizet; 03.01.2014
comment
в Java6 repaint() работает, но в Java7 есть некоторые изменения в API, и почти все потокобезопасные методы в Java6 больше не являются потокобезопасными, вот несколько сообщений о том, чтобы избежать любых предположений об использовании Swing Timer с Swing Действие/ActionListener - person mKorbel; 03.01.2014
comment
вы не можете зацикливаться на периоде в 10 миллисекунд на стандартном ПК, это находится под задержкой для стандартной родной ОС (это значение лучше в Win8/8.1), используйте 25/33 в качестве стандарта - person mKorbel; 03.01.2014
comment
вы можете протестировать isEventDispatchThread, должны признать, что логика для EDT очень проста, EDT существует, возвращает true до тех пор, пока одно событие не будет нажато в очереди, не существует, возвращает false в случае, если все события сбрасываются, выполняются или завершаются макс. значение 10-15 секунд - person mKorbel; 03.01.2014

Прежде всего большое спасибо за редактирование и форматирование вашего вопроса. Это очень помогает при ответе на ваш вопрос.

Также я должен признать, что я не на 100% уверен в своих ответах, поэтому, ребята: не стесняйтесь поправлять меня, если я ошибаюсь.

  1. Все, что изменяет ваш графический интерфейс пользователя.

  2. Не совсем уверен в этом.

  3. Если вам нужно обновить графический интерфейс с помощью трудоемких вычислений. Например, если вы хотите показать числа от 0 до 100000000 в JLabel.

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

person dehlen    schedule 03.01.2014
comment
Ваши ответы на вопросы 1 и 2 на самом деле отвечают на вопрос, что должно работать внутри (или вне) EDT. Не вопрос ОП, который заключается в том, что по умолчанию работает внутри или вне EDT. - person JB Nizet; 03.01.2014
comment
да, я запутался в цифрах и отредактировал свой ответ ... я думаю, что теперь он должен быть правильным, но я думаю, что ваши ответы намного точнее, поэтому я проголосовал за вас ;-) - person dehlen; 03.01.2014