1

我的程序中有一个事件处理程序系统,插件可以在其中注册事件侦听器。
使用此方法调用事件。

/**
 * Pass an event to registered {@link EventHandler}s.
 *
 * @param event Event to pass.
 */
public void callEvent(Event event) {
    synchronized (this) {
        HandlerList handlers = event.getHandlers();
        List<RegisteredListener> listeners = handlers.getRegisteredListeners();
        for (RegisteredListener registration : listeners) {
            try {
                registration.callEvent(event);
            } catch (Throwable ex) {
                Log.e(TAG, "Could not pass event " + event.getClass().getSimpleName() + " to " + registration.getListener().getClass().getName(), ex);
            }
        }
    }
}

HandlerList只是一个容器List<RegisteredListener>

一些事件侦听器在被调用后需要注销,这会导致ConcurrentModificationException循环中。该系统对性能至关重要,我想避免List.toArray()为每个事件做或类似的副本;通常有 100 个事件的块。如何允许从子侦听器修改列表?

4

1 回答 1

4

几点评论:

  • 你可以把你的监听器放在一个CopyOnWriteArrayList非常适合这种类型的操作中(它会阻止 CME)并且不需要显式锁定
  • List.toArray非常快(复制大小为 100 的列表应该不到一微秒)
  • 您应该尽量不要从同步块 ( registration.callEvent(event)) 中调用外来方法,因为这可能会导致烦人的错误,例如死锁。
于 2013-05-28T10:41:23.633 回答