Browse Source

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
pull/23223/head
Brian Clozel 7 years ago
parent
commit
1b93ea97ac
  1. 5
      spring-core/src/main/java/org/springframework/util/MimeTypeUtils.java

5
spring-core/src/main/java/org/springframework/util/MimeTypeUtils.java

@ -443,6 +443,11 @@ public abstract class MimeTypeUtils { @@ -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) {

Loading…
Cancel
Save