Search |
||
Good advice for coding listenersPosted by emcmanus on July 29, 2005 at 4:01 AM PDT
The consistently excellent Brian Goetz has written a new article in his Java Theory and Practice series entitled "Be a good (event) listener". Since listeners are an important part of the JMX API, here's how his advice applies there. There are really two sets of recommendations, one for event generators and one for event listeners. In the JMX API, events are instances of
The advice for event generators (
Fortunately, the standard implementation class
If you have an MBean that sends notifications, it is almost always best to use
public class Something extends SomethingElse
implements SomethingMBean, NotificationEmitter {
private final NotificationBroadcasterSupport nbs =
new NotificationBroadcasterSupport();
private static final MBeanNotificationInfo[] notificationInfo = {...};
public void addNotificationListener(NotificationListener nl,
NotificationFilter nf,
Object handback) {
nbs.addNotificationListener(nl, nf, handback);
}
public MBeanNotificationInfo[] getNotificationInfo() {
return notificationInfo.clone();
}
...the two removeNotificationListener methods delegate like
addNotificationListener...
...code that wants to send a notification does:
Notification n = ...;
nbs.sendNotification(n);
}
In Java SE 6 (Mustang), Concerning event listeners, Brian Goetz has four pieces of advice:
I haven't noticed people doing the first thing in this list, but if you have, now you know you should stop. The second is very good advice, and in particular you should pay attention to exceptions. You should be sure that every Paying attention to thread safety is just as important for listeners in the JMX API as elsewhere. Finally, listeners should not block. If a local listener blocks, meaning a listener that is in the same Java Virtual Machine as the MBean sending the notification, then that will usually cause the sending MBean to block too until the listener completes. If a remote listener blocks, it won't hold up the sending MBean, but it will prevent the delivery of any other notifications from the same connection until it finishes. If you need to do a blocking operation, you won't want to use the
class BlockingListener implements NotificationListener {
public void handleNotification(Notification n, Object handback) {
blockingOperation();
}
}
...into this one...
class NonBlockingListener implements NotificationListener {
private final Executor executor =
Executors.newSingleThreadExecutor();
public void handleNotification(Notification n, Object handback) {
executor.execute(new Runnable() {
public void run() {
blockingOperation();
}
});
}
}
This creates a private thread that will handle the call to If you have many listeners where you need to do blocking operations like this, you might consider sharing a Finally, if you have an MBean that absolutely must not block when it sends a notification, even in the face of a badly-behaved listener that does block, then Mustang provides another
new constructor for »
Related Topics >>
Open JDK Comments
Comments are listed in date ascending order (oldest first)
|
||
|
|