Synchronize RedisCache.get(…) with ValueLoader only if value is absent.

RedisCache.get(…) now optimistically fetches the cache value before entering cache-wide synchronization. The previous version synchronized all calls to `get(key, valueLoader)`.

Closes #2079
Original pull request: #2082.
This commit is contained in:
Piotr Mionskowski
2021-06-10 23:04:16 +02:00
committed by Mark Paluch
parent 5747c7d5e6
commit 30aeda562b
2 changed files with 57 additions and 8 deletions

View File

@@ -44,6 +44,7 @@ import org.springframework.util.ReflectionUtils;
*
* @author Christoph Strobl
* @author Mark Paluch
* @author Piotr Mionskowski
* @see RedisCacheConfiguration
* @see RedisCacheWriter
* @since 2.0
@@ -118,7 +119,7 @@ public class RedisCache extends AbstractValueAdaptingCache {
*/
@Override
@SuppressWarnings("unchecked")
public synchronized <T> T get(Object key, Callable<T> valueLoader) {
public <T> T get(Object key, Callable<T> valueLoader) {
ValueWrapper result = get(key);
@@ -126,6 +127,17 @@ public class RedisCache extends AbstractValueAdaptingCache {
return (T) result.get();
}
return getSynchronized(key, valueLoader);
}
@SuppressWarnings("unchecked")
private synchronized <T> T getSynchronized(Object key, Callable<T> valueLoader) {
ValueWrapper result = get(key);
if (result != null) {
return (T) result.get();
}
T value = valueFromLoader(key, valueLoader);
put(key, value);
return value;