В моем дизайне есть объект, у которого есть слушатели. Эти слушатели получают сигнал об определенном событии, которое может происходить до сотни раз в секунду.
Я делал что-то вроде этого:
private void notifyListeners(ObjectEvent o) {
synchronized (this.listeners) {
for (ObjectListener l: this.listeners)
l.eventFired(o);
}
}
Проблема здесь в том, что кто-то может реализовать метод eventFired
, который затем оборачивается и ждет synchronize
объекта, который удерживается другим потоком, который пытается добавить или удалить слушателя и ожидает на synchronized(this.listeners)
строка.
Итак, я изменил метод notifyListeners
таким образом:
private ObjectListener[] getObjectListeners() {
synchronized (this.listeners) {
return this.listeners.toArray(new ObjectListener[this.listeners.size()]);
}
}
private void notifyListeners(ObjectEvent o) {
ObjectListener[] listeners = this.getObjectListeners();
for (ObjectListener l: listeners)
l.eventFired(o);
}
Меня беспокоит влияние создания этого массива каждый раз при запуске объекта и его влияние на использование памяти приложением.
Так что я здесь, чтобы спросить, есть ли лучший способ. Возможно, я только что нашел это. Было бы достаточно легко создать ObjectListener[]
каждый раз, когда я добавляю или удаляю слушателя, а затем просто выполняю итерацию без синхронизации каждый раз, когда происходит событие. Я собираюсь внести это изменение сейчас, а затем посмотреть, есть ли здесь лучшая идея.