Can LinkedHashMap(accessOrder=true) be guarded by ReadWriteLock ?
Remi Forax
forax at univ-mlv.fr
Thu Nov 7 08:28:51 UTC 2024
----- Original Message -----
> From: "Andrey Turbanov" <turbanoff at gmail.com>
> To: "core-libs-dev" <core-libs-dev at openjdk.java.net>
> Sent: Thursday, November 7, 2024 9:17:00 AM
> Subject: Can LinkedHashMap(accessOrder=true) be guarded by ReadWriteLock ?
> 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
Hello Andrey,
yes !
This flavor of LinkedHashMap has always been a little dubious because having a Map.get() that does a structural modification can be qualified at best as surprising, at worst as not compliant with the contract of Map.
regards,
Rémi
More information about the core-libs-dev
mailing list