You said that multiple threads are accessing this map. This could indeed cause the NPE in the remove
operation of a LinkedHashMap.Entry
instance. This is the implementation of this method:
private void remove() {
before.after = after;
after.before = before;
}
Here before
and after refer
to the linked predecessor and successor of the current entry. If another thread already changed the linking between the entries, this could of course result in an unexpected behavior, such as the NPE.
The solution is - you guessed correctly - to wrap your produced map in a synchronized map. Such as:
public static <K, V> Map<K, V> createLRUMap(final int maxEntries) {
Map<K,V> result = new LinkedHashMap<K, V>(maxEntries*3/2, 0.7f, true) {
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > maxEntries;
}
};
return Collections.synchronizedMap(result);
}
This synchronized wrapper will indeed synchronize all calls to the underlying map, so only one single thread is allowed to go through each method (such as get, put, contains, size, and so on).