Fix concurrent reads issue in MimeTypeUtils cache

As of gh-22340, `MimeTypeUtils` has a built-in LRU cache implementation
for caching parsed MIME types and avoiding excessive garbage creation at
runtime.
This implementation, when hit with highly concurrent reads on the same
media type (the cache key), can create multiple keys for the same MIME
type string. This duplication leads to the cache filling up and evicting
entries. When the cache fetches a duplicate key, it is then not
associated with a value and the cache can return a `null` value, which
is forbidden by the API contract.

This commit adds another cache check within the write lock: this avoids
creating duplicate entries in the cache and `null` return values.

Fixes gh-23211
This commit is contained in:
Brian Clozel
2019-06-28 23:43:38 +02:00
parent 5bf070a857
commit 1b93ea97ac

View File

@@ -443,6 +443,11 @@ public abstract class MimeTypeUtils {
}
this.lock.writeLock().lock();
try {
// retrying in case of concurrent reads on the same key
if (this.queue.remove(key)) {
this.queue.add(key);
return this.cache.get(key);
}
if (this.queue.size() == this.maxSize) {
K leastUsed = this.queue.poll();
if (leastUsed != null) {