From 3096888c7d5bef95e652833bdde96f9505ff33c5 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 5 Jul 2016 16:44:07 +0200 Subject: [PATCH] Better synchronization in ConcurrentMapCache Issue: SPR-13810 --- .../cache/concurrent/ConcurrentMapCache.java | 16 +++++--------- .../concurrent/ConcurrentMapCacheTests.java | 22 +++++++++---------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCache.java b/spring-context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCache.java index df41bf5f50..9cb947f181 100644 --- a/spring-context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCache.java +++ b/spring-context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCache.java @@ -59,7 +59,7 @@ public class ConcurrentMapCache extends AbstractValueAdaptingCache { * @param name the name of the cache */ public ConcurrentMapCache(String name) { - this(name, new ConcurrentHashMap(256), true); + this(name, new ConcurrentHashMap<>(256), true); } /** @@ -69,7 +69,7 @@ public class ConcurrentMapCache extends AbstractValueAdaptingCache { * values for this cache */ public ConcurrentMapCache(String name, boolean allowNullValues) { - this(name, new ConcurrentHashMap(256), allowNullValues); + this(name, new ConcurrentHashMap<>(256), allowNullValues); } /** @@ -141,20 +141,14 @@ public class ConcurrentMapCache extends AbstractValueAdaptingCache { return (T) get(key).get(); } else { - synchronized (this.store) { - if (this.store.containsKey(key)) { - return (T) get(key).get(); - } - T value; + return (T) fromStoreValue(this.store.computeIfAbsent(key, r -> { try { - value = valueLoader.call(); + return toStoreValue(valueLoader.call()); } catch (Exception ex) { throw new ValueRetrievalException(key, valueLoader, ex); } - put(key, value); - return value; - } + })); } } diff --git a/spring-context/src/test/java/org/springframework/cache/concurrent/ConcurrentMapCacheTests.java b/spring-context/src/test/java/org/springframework/cache/concurrent/ConcurrentMapCacheTests.java index 6836ba7030..58e44a4cc6 100644 --- a/spring-context/src/test/java/org/springframework/cache/concurrent/ConcurrentMapCacheTests.java +++ b/spring-context/src/test/java/org/springframework/cache/concurrent/ConcurrentMapCacheTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 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. @@ -44,9 +44,9 @@ public class ConcurrentMapCacheTests extends AbstractCacheTests(); - cache = new ConcurrentMapCache(CACHE_NAME, nativeCache, true); - cache.clear(); + this.nativeCache = new ConcurrentHashMap<>(); + this.cache = new ConcurrentMapCache(CACHE_NAME, this.nativeCache, true); + this.cache.clear(); } @Override @@ -84,9 +84,9 @@ public class ConcurrentMapCacheTests extends AbstractCacheTests