Good point.

I use CopyOnWriteArrayList to overcome the same problem.
Results in much less code, and since the bulk of listener lists are
typically very small (0-2 items), generally pretty cheap.

Regards, Noel.

Niclas Hedhman wrote:
> Guys,
> I am looking at the implementation of listeners, a topic I think I am
> pretty good at.
>
> AFAICT, you have exposed yourself to intermittent
> ConcurrentModificationExceptions since the event firing and listener
> list modifications are against the same list. If a new listener is
> added/removed while the events are being fired/handled, it seems that
> CME will be thrown.
>
> To overcome this, I normally use the following pattern;
>
> public void addAbcListener( AbcListener listener )
> {
>     ArrayList listeners = new ArrayList();
>     listeners.putAll( this.abcListeners );
>     listeners.add( listener );
>     synchronized( this )
>     {
>         this.abcListeners = listeners;
>     }
> }
>
> public void fireEvent( ... )
> {
>     Iterator it;
>     synchronized( this )
>     {
>         it = abcListeners.iterator();
>     }
>     while( it.hasNext() )
>     {
>         AbcListener listener = it.next();
>         try
>         {
>             listener.someMethod( ... );
>         } catch( Excption e )
>         {
>             // delegate caught exception to some system.
>        }
>     }
> }
>
>
> This ensures that CME won't happen, as the Iterator is not backed by
> the List where the modifications are occurring. If synchronized is
> considered too expensive, I think it would also work if the
> this.abcListener is volatile, but that is not verified.
>
>
> Cheers
>   

Reply via email to