有一个地图按类型保存相同事件的事件监听器列表作为键,
func_1()
将开始从映射中获取一种类型的侦听器列表并迭代列表以处理每个侦听器的事件。
当一个侦听器完成其处理时,它会要求将其从地图中的侦听器列表中删除。
因为侦听器位于迭代器中,将其从原始列表中删除将导致java.util.ConcurrentModificationException
获取iterator.previous()
下一个侦听器。
问题是如果使用 CopyOnWriteArrayList 复制侦听器列表然后对其进行迭代器,因为它是列表的副本,当侦听器从其他线程中删除时它仍然会抛出吗?
只是简单地制作普通列表的副本而不是CopyOnWriteArrayList
迭代器有什么区别吗?
func_1(Event event) {
List<WeakReference<EventListener<Event>>> listenerlist = mEventMap.get(event.eventType);
/* instead of directly iterator on the listenerlist
ListIterator<WeakReference<EventListener<Event>>> listenerIterator =
listenerlist.listIterator(listenerlist.size());
but making a CopyOnWriteArrayList first:
*/
List<WeakReference<EventListener<Event>>> listeners =
new CopyOnWriteArrayList<>(listenerlist);
ListIterator<WeakReference<EventListener<Event>>> listenerIterator =
listeners.listIterator(listeners.size());
while(listenerIterator.hasPrevious()){
WeakReference<EventListener<Event>> listenerItem =
listenerIterator.previous();
//doing something
listenerItem.func_2(event);
}
}
EventListener::func_2(Event event){
//do something
//remove the type in the map
funct_3(EventListener.this);
}
funct_3(EventListener listener) {
List<WeakReference<EventListener<Event>>> listeners =
mEventMap.get(listener.eventType);
if (listeners != null) {
Iterator<WeakReference<EventListener<Event>>> listenerIterator =
listeners.iterator();
while (listenerIterator.hasNext()) {
WeakReference<EventListener<Event>> listenerItem = listenerIterator.next();
if (listenerItem.get() != null && listenerItem.get() == listener) {
listenerIterator.remove();
break;
}
}
}
}