com.holub.tools
Class Publisher

java.lang.Object
  extended by 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.


Nested Class Summary
static interface Publisher.Distributor
           
 
Constructor Summary
Publisher()
           
 
Method Summary
 void cancelSubscription(Object subscriber)
           
 void publish(Publisher.Distributor deliveryAgent)
          Publish an event using the deliveryAgent.
 void subscribe(Object subscriber)
           
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

Publisher

public Publisher()
Method Detail

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)