Java Reference
In-Depth Information
22. new RouterWorkThread(message, destinations);
23. }
24.
25. public void addRoute(InputChannel source, OutputChannel[] destinations) {
26. links.put(source, destinations);
27. }
28.
29. private class RouterWorkThread implements Runnable{
30. private OutputChannel [] destinations;
31. private Message message;
32. private Thread runner;
33.
34. private RouterWorkThread(Message newMessage, OutputChannel[] newDestinations){
35. message = newMessage;
36. destinations = newDestinations;
37. runner = new Thread(this);
38. runner.start();
39. }
40.
41. public void run() {
42. for (int i = 0; i < destinations.length; i++){
43. try{
44. destinations[i].sendMessage(message);
45. }
46. catch(RemoteException exc){
47. System.err.println("Unable to send message to " + destinations[i]);
48. }
49. }
50. }
51. }
52. }
When using the Router pattern, be careful about the size of message to be delivered. Generally, the message
should be as small as possible. It is easy to be fooled by some Java objects, though. An object might have
references to other objects, which refer to other objects, and so on—and what seemed like a small object might
turn out to be very large indeed. For instance, sending a
java.awt.Button
is not a good idea, because the whole
GUI will be serialized and sent.
It's a lot like buying your child a toy in a store. The purchase of a single Out-law Robot Laser Geek might not
seem expensive at first, but by the time you get all the accessories (extra laser pistol, laser-spitting horn-rimmed
glasses), you might wonder if it would just be cheaper to buy him or her a sweater.
In this example, the
InputKey
class implements the
InputChannel
interface. It must be sent to the Router using
RMI, so this class must redefine the
hashCode
and
equals
methods to make sure objects on different JVMs can
be tested for equality.
Example A.249
InputKey.java
1. public class InputKey implements InputChannel{
2. private static int nextValue = 1;
3. private int hashVal = nextValue++;
4. public int hashCode(){ return hashVal; }
5. public boolean equals(Object object){
6. if (!(object instanceof InputKey)){ return false; }
7. if (object.hashCode() != hashCode()){ return false; }
8. return true;
9. }
10. }
The
RouterClient
class provides a client to the
Router
; this class both sends and receives messages using RMI.
The method
sendMessageToRouter
transmits a message to the central router, and the method
sendMessage
(defined by the
OutputChannel
interface) receives messages from the
Router
.
Example A.250
RouterClient.java
1. import java.rmi.Naming;
2. import java.rmi.server.UnicastRemoteObject;
3. import java.rmi.RemoteException;
4. public class RouterClient implements OutputChannel{
5. private static final String ROUTER_CLIENT_SERVICE_PREFIX = "routerClient";
6. private static final String ROUTER_SERVER_MACHINE_NAME = "localhost";
7. private static final String ROUTER_SERVER_SERVICE_NAME = "router";
8. private static int clientIndex = 1;
9. private String routerClientServiceName = ROUTER_CLIENT_SERVICE_PREFIX + clientIndex++;