ericliu

@eric.liu.developer

Using WeakHashMap to save references of callbacks

According to ‘Effective Java, 2nd Edition’, “ … The best way to ensure that callbacks are garbage collected promptly is to store only weak refer- ences to them, for instance, by storing them only as keys in a WeakHashMap.”

There is an example in JDK source code which uses WeakHashMap to save callbacks to prevent memory leak.

Let’s look at the class

BaseResourceFactory

There is a field: listenerMap

, which is a WeakHashMap that saves listeners that are being added.

// Use a WeakHashMap as it automatically removes dead objects when they're
// collected
private final WeakHashMap<ResourceFactoryListener,Boolean> listenerMap =
new WeakHashMap<ResourceFactoryListener,Boolean>();

To add a listener, the client just need to save the listener as the key, and Boolean.TRUE as the value to the map.

@Override public void addFactoryListener(ResourceFactoryListener l) {
listenerMap.put(l, Boolean.TRUE);
}

Why using Boolean.TRUE?

Because it is a constant object:

public static final Boolean TRUE = new Boolean(true);

So we are using it as a placeholder without creating any additional object or using any additional memory.

And to get all listeners, the getFactoryListeners method returns a defensive copy of the keySet of the WeahHashMap.

protected ResourceFactoryListener[] getFactoryListeners() {
return listenerMap.keySet().toArray(new ResourceFactoryListener[0]);
}

Lastly, there is remove method.

@Override public void removeFactoryListener(ResourceFactoryListener l) {
// remove will return null if there is no mapping, so it's safe to call
// with unregistered listeners
listenerMap.remove(l);
}

More by ericliu

Topics of interest

More Related Stories