Can LinkedHashMap(accessOrder=true) be guarded by ReadWriteLock ?

Andrey Turbanov turbanoff at gmail.com
Thu Nov 7 08:17:00 UTC 2024


Hello.
I've got a question about LinkedHashMap created with accessOrder=true flag.
Usually this constructor is used when we want to build LRU cache.
https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/LinkedHashMap.html#<init>(int,float,boolean)

        LinkedHashMap<MyKey, MyValue> cache = new LinkedHashMap<>(8, 1f, true) {
            @Override
            protected boolean removeEldestEntry(Map.Entry<MyKey,
MyValue> eldest) {
                return size() > 32;
            }
        };

LinkedHashMap is not a thread-safe data structure, so to be able to
use it in a concurrent environment, access to it should be guarded by
some kind of synchronization.
I often see in many projects that such access is guarded by
ReentrantReadWriteLock.
Example in OpenJDK:
https://github.com/openjdk/jdk/blob/0e1c1b793d43064aabe9571057284899c9580f30/src/java.desktop/share/classes/sun/awt/image/ImageCache.java#L46

private final ReentrantReadWriteLock readWriteLock = new
ReentrantReadWriteLock();

public MyValue get(MyKey key) {
    readWriteLock.readLock().lock();
    try {
        return cache.get(key);
    } finally {
        readWriteLock.readLock().unlock();
    }
}

public void put(MyKey key, MyValue value) {
    readWriteLock.writeLock().lock();
    try {
        cache.put(key, value);
    } finally {
        readWriteLock.writeLock().unlock();
    }
}

I can see in LHM javadoc that LinkedHashMap.get in such a case can
cause structural modification:
"In access-ordered linked hash maps, merely querying the map with get
is a structural modification."

As I understand, it means that LinkedHashMap.get can't be guarded
_just_ by ReadLock.
Is my assumption correct?

Andrey Turbanov


More information about the core-libs-dev mailing list