Skip to content

Commit 6cd6741

Browse files
committed
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
1 parent e427ea8 commit 6cd6741

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

spring-context-support/src/main/java/org/springframework/cache/caffeine/CaffeineCacheManager.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -51,6 +51,7 @@
5151
* @author Juergen Hoeller
5252
* @author Stephane Nicoll
5353
* @author Sam Brannen
54+
* @author Brian Clozel
5455
* @since 4.3
5556
* @see CaffeineCache
5657
*/
@@ -188,8 +189,13 @@ public Collection<String> getCacheNames() {
188189
@Override
189190
@Nullable
190191
public Cache getCache(String name) {
191-
return this.cacheMap.computeIfAbsent(name, cacheName ->
192-
this.dynamic ? createCaffeineCache(cacheName) : null);
192+
if (this.dynamic) {
193+
Cache cache = this.cacheMap.get(name);
194+
return (cache != null) ? cache : this.cacheMap.computeIfAbsent(name, this::createCaffeineCache);
195+
}
196+
else {
197+
return this.cacheMap.get(name);
198+
}
193199
}
194200

195201

0 commit comments

Comments
 (0)