com.holub.tools
Class Publisher
java.lang.Object
com.holub.tools.Publisher
public class Publisher
- extends Object
This class replaces the Multicaster class that's described in
Taming Java Threads. It's better in almost every way
(It's smaller, simpler, faster, etc.). The primary difference
between this class and the original is that I've based
it on a linked-list, and I've used a Strategy object to
define how to notify listeners, thereby makeing the interface
much more flexible.
The Publisher
class provides an efficient thread-safe means of
notifying listeners of an event. The list of listeners can be
modified while notifications are in progress, but all listeners
that are registered at the time the event occurs are notified (and
only those listeners are notified). The ideas in this class are taken
from the Java's AWTEventMulticaster class, but I use an (iterative)
linked-list structure rather than a (recursive) tree-based structure
for my implementation.
Here's an example of how you might use a Publisher
:
class EventGenerator
{ interface Listener
{ notify( String why );
}
private Publisher publisher = new Publisher();
public void addEventListener( Listener l )
{ publisher.subscribe(l);
}
public void removeEventListener ( Listener l )
{ publisher.cancelSubscription(l);
}
public void someEventHasHappend(final String reason)
{ publisher.publish
(
// Pass the publisher a Distributor that knows
// how to notify EventGenerator listeners. The
// Distributor's deliverTo method is called
// multiple times, and is passed each listener
// in turn.
new Publisher.Distributor()
{ public void deliverTo( Object subscriber )
{ ((Listener)subscriber).notify(reason);
}
}
);
}
}
Since you're specifying what a notification looks like
by defining a Listener interface, and then also defining
the message passing symantics (inside the Distributor implementation),
you have complete control over what the notification interface looks like.
Publisher
public Publisher()
publish
public void publish(Publisher.Distributor deliveryAgent)
- Publish an event using the deliveryAgent. Note that this
method isn't synchronized (and doesn't have to be). Those
subscribers that are on the list at the time the publish
operation is initiated will be notified. (So, in theory,
it's possible for an object that cancels its subsciption
to nonetheless be notified.) There's no universally "good"
solution to this problem.
subscribe
public void subscribe(Object subscriber)
cancelSubscription
public void cancelSubscription(Object subscriber)