Avoid lock contention in CaffeineCacheManager
Prior to this commit, using a dynamic `CaffeineCacheManager` would rely on `ConcurrentHashMap#computeIfAbsent` for retrieving and creating cache instances as needed. It turns out that using this method concurrently can cause lock contention even when all known cache instances are instantiated. This commit avoids using this method if the cache instance already exists and avoid storing `null` entries in the map. This change reduces lock contention and the overall HashMap size in the non-dynamic case. Fixes gh-30066
This commit is contained in:
parent
e427ea8086
commit
6cd67412cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -51,6 +51,7 @@ import org.springframework.util.ObjectUtils;
|
|||
* @author Juergen Hoeller
|
||||
* @author Stephane Nicoll
|
||||
* @author Sam Brannen
|
||||
* @author Brian Clozel
|
||||
* @since 4.3
|
||||
* @see CaffeineCache
|
||||
*/
|
||||
|
|
@ -188,8 +189,13 @@ public class CaffeineCacheManager implements CacheManager {
|
|||
@Override
|
||||
@Nullable
|
||||
public Cache getCache(String name) {
|
||||
return this.cacheMap.computeIfAbsent(name, cacheName ->
|
||||
this.dynamic ? createCaffeineCache(cacheName) : null);
|
||||
if (this.dynamic) {
|
||||
Cache cache = this.cacheMap.get(name);
|
||||
return (cache != null) ? cache : this.cacheMap.computeIfAbsent(name, this::createCaffeineCache);
|
||||
}
|
||||
else {
|
||||
return this.cacheMap.get(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue