Разное

Поток диспетчеризации событий java: Многопоточность в Java Swing с SwingWorker

Управление событиями в AggreGate

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

Я согласен

This page is available in English (EN).

Поток событий

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

Фильтрация событий

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

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

Использование выражений позволяет необычайно гибко настраивать фильтры. Вот несколько примеров фильтров на основе выражений:

  • Обнаружение событий, инициированных в определенный промежуток времени
  • Обнаружение событий входа в систему для конкретного пользователя (фильтрация по имени пользователя)
  • Обнаружение событий, содержащих конкретную подстроку в любом поле данных события
  • Обнаружение всех тревог по превышению температуры 120 градусов
  • Фильтрация событий по комбинации условий X и/или Y, а также более сложным условиям

Помимо критериев отбора, настройки фильтров также включают правила отображения событий:

  • Видимость базовых параметров события, например, источника, типа, уровня и подтверждений
  • Видимость полей, зависящих от типа события
  • Пользовательские правила подсветки по уровню события или на основе выражения

Фильтр может быть параметризован, позволяя оператору настраивать критерии выбора события при каждой его активации.

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

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

Агрегация событий

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

Например, если будет зафиксировано множество неудачных попыток входа в систему с неверным паролем, они будут объединены в одно событие «Неудачная попытка аутентификации», включающее в себя запись о количестве дубликатов данного события.

Корреляция событий

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

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

Например, если событие «Активация датчика безопасности периметра», поступившее от телекоммуникационной башни, следует сразу перед событием «Низкий уровень топлива в дизельном генераторе», очевидно, что должна сработать тревога «Кража топлива».

Маскировка событий

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

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

Анализ первопричин

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

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

Обогащение событий

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

Например, событие тревоги может быть обогащено номером заявки в системе Service Desk.

Очереди событий

Как только новое событие проходит стандартный процесс первоначальной обработки, оно переходит в фазу диспетчеризации. Для разных типов событий эта фаза может отличаться:

  • Синхронные события вызываются обработчиками в том же потоке, в котором были инициализированы
  • Наиболее стандартные последовательные события добавляются к основной очереди событий, а затем обрабатываются в потоке диспетчера событий
  • Параллельно работающие события в зависимости от их типа проходят через соответствующие очереди, их обработка выполняется параллельно в выделенном пуле потоков

OpenJDK — Класс EventQueue — Он инкапсулирует асинхронный механизм диспетчеризации событий,который извлекает события из

java.lang.Object

java.awt.EventQueue

public class EventQueue extends Object

EventQueue — это независимый от платформы класс, который ставит в очередь события как из базовых одноранговых классов, так и из доверенных классов приложений.

Он инкапсулирует механизм асинхронной диспетчеризации событий, который извлекает события из очереди и отправляет их, вызывая метод

dispatchEvent(AWTEvent) для этого EventQueue с отправляемым событием в качестве аргумента. Конкретное поведение этого механизма зависит от реализации. Единственное требование состоит в том, что события, которые были фактически помещены в эту очередь (обратите внимание, что события, отправленные в EventQueue , могут быть объединены), отправлялись:

Sequentially.
То есть,не допускается одновременная отправка нескольких событий из этой очереди.
В том же порядке,в каком они были зарегистрированы.
То есть, если AWTEvent A помещен в очередь EventQueue перед AWTEvent B, то событие B не будет отправлено перед событием A.

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

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

Для получения информации о проблемах многопоточности механизма диспетчеризации событий см . Проблемы с многопоточностью AWT .

Since:
1.1

Резюме конструктора

ConstructorDescription
EventQueue()

Инициализирует новый экземпляр EventQueue .

Резюме метода

Модификатор и типMethodDescription
SecondaryLoop
createSecondaryLoop()

Создает новый secondary loop связанный с этой очередью событий.

protected voiddispatchEvent(AWTEvent event)

Отправляет событие.

static AWTEventgetCurrentEvent()

Возвращает событие, которое в настоящее время отправляется EventQueue , связанным с вызывающим потоком.

static longgetMostRecentEventTime()

Возвращает метку времени самого последнего события, имеющего метку времени, и которое было отправлено из EventQueue , связанного с вызывающим потоком.

AWTEvent
getNextEvent()

Удаляет событие из EventQueue и возвращает его.

static voidinvokeAndWait(Runnable runnable)

Вызывает runnable вызов метода run в run dispatch thread системы the system EventQueue .

static voidinvokeLater(Runnable runnable)

Вызывает runnable вызов метода run в run dispatch thread системы the system EventQueue .

static booleanisDispatchThread()

Возвращает true, если вызывающий поток является the current AWT EventQueue .

AWTEventpeekEvent()

Возвращает первое событие в EventQueue , не удаляя его.

AWTEventpeekEvent(int id)

Возвращает первое событие с указанным id,если таковое имеется.

protected voidpop()

Останавливает отправку событий с помощью этого EventQueue .

voidpostEvent(AWTEvent theEvent)

EventQueue событие в стиле 1.1 в EventQueue .

voidpush(EventQueue newEventQueue)

Заменяет существующую EventQueue на указанную.

Методы, объявленные в классе java.

lang. Объект

clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Конструктор Детали

EventQueue

public EventQueue()

Инициализирует новый экземпляр EventQueue .

Методы Подробнее

postEvent

public void postEvent(AWTEvent theEvent)

EventQueue событие в стиле 1.1 в EventQueue . Если есть существующее событие в очередь с тем же ID и события источника, источник Component «ы coalesceEvents метод будет вызываться.

Parameters:
theEvent — экземпляр java.awt.AWTEvent или его подкласс
Throws:
NullPointerException — если theEvent равно null

getNextEvent

public AWTEvent getNextEvent() throws InterruptedException

Удаляет событие из EventQueue

и возвращает его. Этот метод будет блокироваться до тех пор, пока событие не будет опубликовано другим потоком.

Returns:
следующее AWTEvent
Throws:
InterruptedException — если какой-либо поток прервал этот поток

peekEvent

public AWTEvent peekEvent()

Возвращает первое событие в EventQueue , не удаляя его.

Returns:
первое событие

peekEvent

public AWTEvent peekEvent(int id)

Возвращает первое событие с указанным id,если таковое имеется.

Parameters:
id — id желаемого типа события
Returns:
первое событие с указанным идентификатором или null , если такого события нет

dispatchEvent

protected void dispatchEvent(AWTEvent event)

Отправляет событие.Способ отправки события зависит от типа события и типа объекта-источника события:

Типы событий,типы источников и методы диспетчеризации
Тип событияТип источникаОтправлено в
ActiveEventAnyevent. dispatch()
OtherComponentsource.dispatchEvent(AWTEvent)
OtherMenuComponentsource.dispatchEvent(AWTEvent)
OtherOtherБездействие (игнорируется)

Parameters:
event — экземпляр java.awt.AWTEvent или его подкласс
Throws:
NullPointerException — если event равно null
Since:
1.2

© 1993, 2022, Oracle и/или ее дочерние компании. Все права защищены.
Документация,извлечённая из пакета пакетов разработки Debian OpenJDK.
Лицензируется по Стандартной общественной лицензии GNU,версия 2,с исключением Classpath.
Различный код сторонних разработчиков в OpenJDK лицензируется под разными лицензиями (см.пакет Debian).
Java и OpenJDK являются торговыми марками или зарегистрированными торговыми марками компании Oracle и/или ее филиалов.
https://docs.oracle.com/en/java/javase/18/docs/api/java.desktop/java/awt/EventQueue.html

java — Как узнать, нахожусь ли я в потоке отправки событий?

1.Учтите, что мой код находится в какой-то строке JPanel, которая у меня есть, я автоматически перехожу к EDT?

2. Тот же вопрос для всех других классов, которые не принадлежат к GUI, JPanels или другим классам представлений, простому логическому классу.

3. Если у меня есть JPanel, в котором я проигрываю музыку, находясь в ней, должна ли музыка запускаться в потоке отправки событий или в другом потоке, который не является EDT (для того, чтобы не блокировать графический интерфейс, хотя я не чувствовал никаких проблем) с запуском его из EDT)?

Примечание: я хочу общее правило, как узнать его без использования SwingUtilities. 6

  1. Фоновая ветка.

Если код, работающий за пределами EDT, вызывает метод, определенный в классе GUI, этот код будет выполняться не в EDT, а в вызывающем потоке.

Если код, работающий в EDT, вызывает код, определенный в классе, отличном от GUI, этот код будет выполняться в EDT.

Правило состоит в том, что если вы не создаете другой поток, вызываемый вами метод будет выполняться в потоке, из которого выполняется вызывающий код — потоки не соответствуют тем, в каких классах определены методы.

Методы, которые будут работать в EDT прослушивателя событий , когда они вызываются Swing, а не вами. (Хотя они все еще могут быть, если вы звоните им из EDT.)

Кроме того, любой код внутри метода Runnable.run() , переданный в SwingUtilities.invokeLater() и invokeAndWait() , также выполняется в EDT.

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

Любой код, вызываемый из создаваемого вами потока Thread (независимо от того, используете ли вы потоки напрямую, или ExecutorService , или SwingWorker. doInBackground() ), имеет значение , а не в EDT. Ваша программа main() 9Метод 0010 также , а не в EDT.

4

Согласно моему комментарию: когда ничего не помогает, класс SwingUtilities имеет статический метод, который вы можете использовать: SwingUtilities.isEventDispatchThread()

Что касается номера 3), обязательно используйте фоновый поток.

Насколько я знаю, "общего правила" не существует. Да, код в вашем GUI должен быть на EDT, но если у вас где-то есть ошибка, ее может и не быть, хотя обычно она есть. То же самое для слушателей Swing.

0

Зарегистрируйтесь или войдите в систему

Зарегистрируйтесь с помощью Google

Зарегистрироваться через Facebook

Зарегистрируйтесь, используя электронную почту и пароль

Опубликовать как гость

Электронная почта

Требуется, но никогда не отображается

Опубликовать как гость

Электронная почта

Требуется, но не отображается

java - Что такое поток диспетчеризации событий?

Задавать вопрос

спросил

Изменено 12 лет, 8 месяцев назад

Просмотрено 2к раз

Я знаю, что означает «поток», и понимаю ли я поток диспетчеризации событий (EDT) как "просто нить", это многое объясняет, но, видимо, не все.

Я не понимаю, что особенного в этой теме. Например, я не понимаю, почему мы должны запускать GUI в EDT? Почему «основной» поток предназначен для графического интерфейса? Ну, если мы просто не хотим занимать основной поток, почему мы не можем запустить GUI просто в «другом потоке», почему это должен быть какой-то «специальный» поток, называемый EDT?

Тогда я не понимаю, почему мы не можем запустить EDT как любой другой поток? Почему мы должны использовать какой-то специальный инструмент (называемый invokeLater ). И почему GUI, в отличие от любого другого потока, не запускается сразу. Мы должны подождать, пока он не будет готов принять нашу работу. Это потому, что EDT потенциально может выполнять несколько задач одновременно?

Если вы решите ответить на этот вопрос, не могли бы вы использовать очень простую терминологию, иначе, боюсь, я не смогу понять ответ.

ДОБАВЛЕНО:

Я всегда думал, что у нас есть одна "задача" на поток. Итак, в каждом потоке мы выполняем предопределенную последовательность команд. Но мне кажется, что в потоке диспетчеризации событий у нас может быть разорванная задача. Ну, они не выполняются одновременно (поток переключается между разными задачами, но в одном потоке все еще есть несколько задач). Это правильно? Например, в EDT есть один поток, который отображает главное окно, а затем в дополнение к этому мы отправили в EDT еще одну задачу, которая должна обновить один из компонентов окна, и EDT будет выполнять эту новую задачу всякий раз, когда она будет готова. Отличается ли EDT от других потоков в этом отношении?

  • Java
  • пользовательский интерфейс
  • многопоточность

1

Поток диспетчеризации событий — это поток, который обрабатывает все события графического интерфейса и управляет вашим графическим интерфейсом Swing. Он запускается где-то в коде Swing, если в вашей программе есть графический интерфейс. Причина, по которой это делается за кулисами, заключается в простоте — вам не нужно беспокоиться о запуске и управлении дополнительным потоком самостоятельно.

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

Подробнее о параллелизме в Swing и потоке диспетчеризации событий можно прочитать в учебнике Sun по параллелизму в Swing. Кроме того, если вы хотите увидеть, как это можно сделать по-другому, вы можете проверить инструментарий SWT. В SWT вы должны управлять EDT самостоятельно.

Я всегда думал, что у нас есть один «задача» на поток. Итак, в каждой теме мы выполняем предопределенную последовательность команды. Но мне кажется, что в поток диспетчеризации событий, который мы можем есть серьезная задача. Ну, они не выполняются одновременно (поток переключается между разными задачами, но есть еще несколько задач в одной нить). Это правильно? Например в EDT есть один поток, который отобразить главное окно, а затем дополнительно к этому мы отправили в EDT другая задача, которая должна обновить один из компонентов окна и EDT будет выполнять эту новую задачу всякий раз, когда она готово. Отличается ли EDT от других темы таким образом?

Нет, EDT принципиально не отличается от других потоков. А «задача» — неподходящее слово, потому что ее можно спутать с процессами уровня ОС (которые также часто называют задачами). Лучше использовать Runnable , интерфейс, используемый для передачи кода EDT для выполнения через invokeLater() .

EDT в основном связан с очередью вещей, которые он должен делать. Когда пользователь нажимает кнопку в графическом интерфейсе, Runnable , который уведомляет всех прослушивателей, прикрепленных к кнопке, помещается в очередь. При изменении размера окна появляется Runnable , выполняющий повторную проверку и перерисовку, переходит в очередь. И когда вы используете invokeLater() , ваш Runnable попадает в очередь.

EDT просто запускает бесконечный цикл, который говорит: «Возьмите Runnable из очереди (и если он пустой, пока вы не получите уведомление, что это не так) и выполните его.

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

 Что такое EDT?
 

Это хакерский обходной путь для решения многих проблем параллелизма, которые есть в Swing API 😉

Серьезно, многие компоненты Swing не являются "потокобезопасными" (некоторые известные программисты дошли до того, что назвали Swing "поточно-враждебным"). Имея уникальный поток, в котором все обновления делаются для компонентов, враждебных потоку, вы избегаете многих потенциальных проблем параллелизма. В дополнение к этому вам также гарантируется, что он будет запускать Runnable, который вы проходите через него с помощью invokeLater в последовательном порядке.

Обратите внимание, что дело не только в том, что вы уклоняетесь от проблемы параллелизма: вы должны соблюдать рекомендации Sun относительно того, что должно и что не должно делаться в EDT, иначе у вас возникнут серьезные проблемы в вашем приложении.

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

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

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

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

Итак, решение: вызывать методы Swing только из одного потока. Это поток EDT - он не является чем-то особенным, кроме того, что это поток, предназначенный для вызова методов свинга.

Теперь вы можете спросить, почему методы Swing не являются потокобезопасными? После нескольких безуспешных попыток разработчики инструментальных средств GUI обнаружили, что по своей сути невозможно спроектировать безопасный для потоков инструментарий GUI.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *