2011-11-24 156 views
2

大多数人使用ConcurrentLinkedQueue或CopyOnWriteArrayList来收集侦听器,并在事件发生时通知他们。这样做的缺点是,听众可能会在自己已经注销时收到通知。如果经理(集合,...,给它一个名字)遍历监听器集合,并且某个监听器在该迭代期间取消注册,则会发生这种情况。当侦听器被移除时,是否可以再次在该侦听器上调用该事件?

因此,'删除监听者'合同被打破。你会认为这是一个问题吗?

+2

合同不是一定要破的。只是听众在移除后会收到一个事件。 – Michael

+0

更正:侦听器*在拆除后可能会再收到一个事件。只有在侦听器迭代完成时,如果侦听器不幸被移除,才会发生这种情况。 – Michael

+0

如果侦听器在该迭代过程中未注册自己,它如何接收另一个事件?除非对未经修改的集合有另一个*迭代? – EJP

回答

4

即使您检查了侦听器仍被注册,但在多线程环境中,您仍然无法确定它在您调用它时仍然被注册。即使对于非多线程的情况,标准实现也是在副本上工作。

+0

因此,由听众实施来筛选即将到来的事件呢? –

+1

@JaperD因为没有人可以..是的。 – Voo

+0

是的,如果这将是一个监听器实现的问题。 –