ImageCache. LinkedHashMap(accessOrder=true) shouldn't be guarded by ReadWriteLock

Andrey Turbanov turbanoff at gmail.com
Wed Oct 16 07:53:57 UTC 2024


Hello.
I've noticed that the class sun.awt.image.ImageCache uses a
non-threadsafe approach to work with LinkedHashMap.
https://github.com/openjdk/jdk/blob/ebc17c7c8d6febd5a887309d1b7a466bcd2cc0a9/src/java.desktop/share/classes/sun/awt/image/ImageCache.java#L46

There is LinkedHashMap field created with accessOrder=true.

    private final LinkedHashMap<PixelsKey, ImageSoftReference> map
            = new LinkedHashMap<>(16, 0.75f, true);

Access to it is guarded with ReentrantReadWriteLock.

public Image getImage(final PixelsKey key){
    final ImageSoftReference ref;
    lock.readLock().lock();
    try {
        ref = map.get(key);
    } finally {
        lock.readLock().unlock();
    }
    return ref == null ? null : ref.get();
}

BUT there is a catch: LinkedHashMap.get method for such a case - can
cause structural modification.

https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/LinkedHashMap.html
> In access-ordered linked hash maps, merely querying the map with get is a structural modification.

It means there is a possible data race.

Andrey Turbanov


More information about the client-libs-dev mailing list