Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Event listener list implementation

Reply
Thread Tools

Event listener list implementation

 
 
Slobodan C
Guest
Posts: n/a
 
      01-22-2004
I am looking for java.util.List implementation for event listeners
that merges several concepts:

1) Jakarta Commons Collection library has a
org.apache.commons.collections.FastArrayList which avoid the overhead
of synchronization using copy-on-write mode. The idea is that when
dominant ops are reads (such as event listener lists) then it is
cheaper to copy entire list before changing it to avoid
synchronization on reads.

2) Related to (1), when firing events using an iterator, iterator
object needs to keep traversing the old copy of a list if the list is
changed during event firings. Although FastArrayList claims to have
this behaviour, it does the opposite and throws the exception (see
Appendix A)

3) As has been discussed many times before, listeners must be
referenced using a weak reference. Would be nice if the list
implementation would take care of it internally and caller need not
worry about it.

My question is if such an implementation exists some place.

Sub question: If you think that (1) and (2) are overkill and
synchronization is simpler and as fast as copy-on-write, tell me why.


Appendix A:

From the Commons Collection 2.1 doc,
org.apache.commons.collections.FastArrayList:

public Iterator iterator()

Return an iterator over the elements in this list in proper
sequence.

IMPLEMENTATION NOTE - If the list is operating in fast mode, an
Iterator is returned, and a structural modification to the list is
made, then the Iterator will continue over the previous contents of
the list (at the time that the Iterator was created), rather than
failing due to concurrent modifications.


Test:

FastArrayList l = new FastArrayList();

l.setFast( false );
l.add("a");
l.add("b");
l.add("c");
l.setFast( true );
System.out.println("FAST = "+ l.getFast());

Iterator seq = l.iterator();
System.out.println("BEFORE "+ seq.next());
l.add("Z");
System.out.println("AFTER "+ seq.next());


FAST = true
BEFORE a
java.util.ConcurrentModificationException
at org.apache.commons.collections.FastArrayList$ListI ter.checkMod(Unknown
Source)
at org.apache.commons.collections.FastArrayList$ListI ter.next(Unknown
Source)
at brisi.main(brisi.java:22)
Exception in thread "main"

According to the doc I should not get the exception since the list is
in fast mode. Yet it is thrown and looking at the source it seems to
be a deliberate check, so no accident. I can only assume that the doc
hasn't been updated.
 
Reply With Quote
 
 
 
 
xarax
Guest
Posts: n/a
 
      01-23-2004
"Slobodan C" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) om...
> I am looking for java.util.List implementation for event listeners
> that merges several concepts:
>
> 1) Jakarta Commons Collection library has a
> org.apache.commons.collections.FastArrayList which avoid the overhead
> of synchronization using copy-on-write mode. The idea is that when
> dominant ops are reads (such as event listener lists) then it is
> cheaper to copy entire list before changing it to avoid
> synchronization on reads.


Don't know about this one...

> 2) Related to (1), when firing events using an iterator, iterator
> object needs to keep traversing the old copy of a list if the list is
> changed during event firings. Although FastArrayList claims to have
> this behaviour, it does the opposite and throws the exception (see
> Appendix A)


When I am ready to fire an event, I make an
array of the current listener list, then
walk the array. The listener list can change
while firing the event, but only the listeners
that were registered at the time of the event
will be notified. Creating the array is an
atomic event (synchronized), so it is somewhat
fast. Walking the array is not synchronized,
because no other thread has a reference to
the array.


> 3) As has been discussed many times before, listeners must be
> referenced using a weak reference. Would be nice if the list
> implementation would take care of it internally and caller need not
> worry about it.


This is not too hard to create an abstract class
implementation of the bare bones, then extend it
with a nested class for handling your specific
event type. Hide the list as a private field and
use instance methods to manage adding, removing,
event firing, etc. Use synchronization as necessary
in those instance methods. ArrayList is fast, and
you can wrap the listener elements with a WeakReference.

> My question is if such an implementation exists some place.
>
> Sub question: If you think that (1) and (2) are overkill and
> synchronization is simpler and as fast as copy-on-write, tell me why.
>
>

/snip/

What is the minimum functionality that you need? Specify
each requirement and be certain that it is a *requirement*,
rather than a "nice to have feature".



 
Reply With Quote
 
 
 
 
Slobodan C
Guest
Posts: n/a
 
      01-23-2004
"xarax" <(E-Mail Removed)> wrote in message news:<AsaQb.24727$(E-Mail Removed) thlink.net>...
> "Slobodan C" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed) om...

.......
>
> > 2) Related to (1), when firing events using an iterator, iterator
> > object needs to keep traversing the old copy of a list if the list is
> > changed during event firings. Although FastArrayList claims to have
> > this behaviour, it does the opposite and throws the exception (see
> > Appendix A)

>
> When I am ready to fire an event, I make an
> array of the current listener list, then
> walk the array. The listener list can change
> while firing the event, but only the listeners
> that were registered at the time of the event
> will be notified. Creating the array is an
> atomic event (synchronized), so it is somewhat
> fast. Walking the array is not synchronized,
> because no other thread has a reference to
> the array.
>
>

.....

Of course, that it is the traditional solution. However, in practice
original array list 99% of the times will not be modified while
iterating over its elements. Thus we end up creating a copy for each
even firing even though it wasn't necessary.

(actually 99% above depends on a particular context ...)

If a system fires a lot of events it adds up to a lot of garbage being
created at a fast clip!

So I'd like an implementation that starts out with an optimistic
assumption that copy is not needed. Then, while iterating over the
original array if a modification call is made then a copy is made.
Something like:

<Event Firing Thread> <Some other Thread>

Iterator i(a) = listeners(a).iterator();
fireEvent( i(a).next() );
....
fireEvent( i(a).next() ); listeners(a).add( this );
.... {copy} listeners(b)
fireEvent( i(a).next() );
-->>>> <Handler>
do stuff
listeners(b).remove( this
);
{copy} listeners(b)
....
fireEvent( i(a).next() ); listeners(a).add( this );
....

This is sort of pseudo-code. The (x) implies a version of a listener
list. So you can see that regardless of changes on the right the
iterator keeps traversing original list (view). Regardless of changes
being made in another thread or one of the handlers, iterator is fine.
{copy} is meant to show that only at the last moment new copy is made.
Thus ideal case would be:

<Event Firing Thread>

Iterator i(a) = listeners(a).iterator();
fireEvent( i(a).next() );
....
fireEvent( i(a).next() );
<done>

So no copying since there is no need.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
having trouble with event listener: detect iframe close event fromparent Mike Scirocco Javascript 4 04-05-2007 03:19 AM
Is There a Keyboard Event Listener? kvnsmnsn@hotmail.com Java 10 03-07-2005 04:31 PM
Java Event Listener integer problem. Mmm_moo_cows Java 4 10-26-2004 03:26 PM
event listener requesting a thread Shrish Java 1 10-16-2004 09:10 AM
SERVLETS: extending j_security_check - filter or event listener? Sasha Borodin Java 0 07-28-2003 08:22 PM



Advertisments